PostgreSQL'de IN ve ANY operatörü karşılaştırması


Yanıtlar:


158

(Ne bir "operatör" ne INde değildir ANY. Bir "yapı" veya "sözdizimi öğesi".)

Mantıksal olarak , kılavuzdan alıntı yaparak :

INeşdeğerdir = ANY.

Ama iki tane vardır sözdizimi varyantları arasında INve iki varyantı ANY. Detaylar:

IN bir set= ANY almak , burada gösterildiği gibi bir set almaya eşdeğerdir :

Ancak her birinin ikinci varyantı diğeriyle eşdeğer değildir. Yapının ikinci varyantı ANYbir dizi alır (gerçek bir dizi türü olmalıdır), ikinci varyantı ise INvirgülle ayrılmış bir değerler listesi alır . Değerlerin geçirilmesi ve farklı kısıtlamalara Bu potansiyel müşteriler olabilir ayrıca özel durumlarda farklı sorgu planları yol:

ANY daha çok yönlü

ANYO sadece çeşitli operatörler, ile kombine edilebilir olarak yapı, çok yönlüdür =. Misal:

SELECT 'foo' LIKE ANY('{FOO,bar,%oo%}');

Çok sayıda değer için, her biri için daha iyi bir ölçek belirleme sağlamak :

İlişkili:

Ters çevirme / zıt / dışlama

" idVerilen dizide bulunan satırları bul ":

SELECT * FROM tbl WHERE id = ANY (ARRAY[1, 2]);

İnversiyon: "satırları bulun idolduğu değil dizideki":

SELECT * FROM tbl WHERE id <> ALL (ARRAY[1, 2]);
SELECT * FROM tbl WHERE id <> ALL ('{1, 2}');  -- equivalent array literal
SELECT * FROM tbl WHERE NOT (id = ANY ('{1, 2}'));

Üçü de eşdeğer. Birincisi dizi yapıcısına sahip , diğer ikisi dizi değişmez değerine sahip . Veri türü, açıkça bağlamdan türetilebilir. Aksi takdirde, gibi açık bir atama gerekli olabilir '{1,2}'::int[].

İle satırlar id IS NULLbu ifadelerden hiçbirini geçmez. NULLEk olarak değerleri eklemek için :

SELECT * FROM tbl WHERE (id = ANY ('{1, 2}')) IS NOT TRUE;

4
İkinci varyantların sonuçlarının her zaman aynı olacağını açıkça belirtmek güzel olurdu. Aslında durumun bu olduğundan% 99 eminim ama cevap bunu ifade etmiyor. Bunun anlamı, potansiyel olarak farklı sorgu planlarına sahip olsalar bile SELECT * from mytable where id in (1, 2, 3), her zaman aynı satırlarla sonuçlanacaktır SELECT * from mytable where id = ANY('{1, 2, 3}').
KPD

1
ANY olamaz birleştirilebilir !=operatör. Belgelendiğini sanmıyorum ama select * from foo where id != ANY (ARRAY[1, 2])aynı şey değil select * from foo where id NOT IN (1, 2). Öte yandan select * from foo where NOT (id = ANY (ARRAY[1, 2]))beklendiği gibi çalışıyor.
qris

1
@qris: operatör ANYile birleştirilebilir !=. Ama daha fazlası var. Yukarıya bir bölüm ekledim. (Bunun <>standart !=
SQL'deki

NULLDeğerleri içeren son sürüm nasıl çalışır? Çalışır mıydı WHERE id = ANY (ARRAY[1, 2]) OR id IS NULL;?
dvtan

1
@dvtan: (id = ...) IS NOT TRUEçalışır çünkü id = ...sadece TRUEgerçek bir eşleşme olup olmadığını değerlendirir . Sonuçlar FALSEveya NULLtestimizi geç. Bkz .: stackoverflow.com/a/23767625/939860 . Eklediğiniz ifade başka bir şey için test eder. Bu eşdeğer olacaktırWHERE id <> ALL (ARRAY[1, 2]) OR id IS NULL;
Erwin Brandstetter

3

Diğer cevabın yanı sıra iki bariz nokta var:

  • Alt sorguları kullanırken tam olarak eşdeğerdirler:

    SELECT * FROM table
    WHERE column IN(subquery);
    
    SELECT * FROM table
    WHERE column = ANY(subquery);

Diğer yandan:

  • Yalnızca INoperatör basit bir listeye izin verir:

    SELECT * FROM table
    WHERE column IN(… ,  , …);

Tamamen aynı olduklarını varsaymak ANY, listelerde işe yaramadığını unuttuğumda beni birkaç kez yakaladı .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.