Qual è la differenza tra IN
e ANY
operator in PostgreSQL?
Il meccanismo di funzionamento di entrambi sembra essere lo stesso. Qualcuno può spiegarlo con un esempio?
Qual è la differenza tra IN
e ANY
operator in PostgreSQL?
Il meccanismo di funzionamento di entrambi sembra essere lo stesso. Qualcuno può spiegarlo con un esempio?
Risposte:
(Né IN
né ANY
è un "operatore". Un "costrutto" o un "elemento di sintassi".)
Logicamente , citando il manuale :
IN
è equivalente a= ANY
.
Ma ci sono due varianti di sintassiIN
e due varianti di ANY
. Dettagli:
IN
prendere un set equivale a = ANY
prendere un set , come dimostrato qui:
Ma la seconda variante di ciascuna non è equivalente all'altra. La seconda variante del ANY
costrutto accetta un array (deve essere un tipo di array effettivo), mentre la seconda variante di IN
accetta un elenco di valori separati da virgole . Ciò porta a diverse restrizioni nel passaggio di valori e può anche portare a diversi piani di query in casi speciali:
=any()
ma utilizzato conin
ANY
è più versatileLa ANY
struttura è molto più versatile, in quanto può essere combinata con vari operatori, non solo =
. Esempio:
SELECT 'foo' LIKE ANY('{FOO,bar,%oo%}');
Per un numero elevato di valori, fornire un set scala meglio per ciascuno:
Relazionato:
"Trova le righe in cui si id
trova nella matrice data":
SELECT * FROM tbl WHERE id = ANY (ARRAY[1, 2]);
Inversione: "Trova righe dove nonid
è nell'array":
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}'));
Tutti e tre equivalenti. Il primo con il costruttore di array , gli altri due con il letterale di array . Il tipo di dati può essere derivato dal contesto in modo univoco. Altrimenti, potrebbe essere richiesto un cast esplicito, come '{1,2}'::int[]
.
Le righe con id IS NULL
non superano nessuna di queste espressioni. Per includere NULL
valori aggiuntivi:
SELECT * FROM tbl WHERE (id = ANY ('{1, 2}')) IS NOT TRUE;
SELECT * from mytable where id in (1, 2, 3)
risulterà sempre nelle stesse righe di SELECT * from mytable where id = ANY('{1, 2, 3}')
, anche se potenzialmente potrebbero avere piani di query diversi.
ANY
non è cumulabile con l' !=
operatore. Non credo sia documentato, ma select * from foo where id != ANY (ARRAY[1, 2])
non è lo stesso di select * from foo where id NOT IN (1, 2)
. D'altra parte, select * from foo where NOT (id = ANY (ARRAY[1, 2]))
funziona come previsto.
ANY
può essere combinato con l' !=
operatore. Ma c'è di più. Ho aggiunto un capitolo sopra. (Si noti che <>
è l'operatore in SQL standard, sebbene !=
sia accettato anche in Postgres.)
NULL
valori? Funzionerebbe WHERE id = ANY (ARRAY[1, 2]) OR id IS NULL;
altrettanto bene?
(id = ...) IS NOT TRUE
funziona perché id = ...
valuta solo TRUE
se esiste una corrispondenza effettiva. Risultati FALSE
o NULL
supera il nostro test. Vedi: stackoverflow.com/a/23767625/939860 . La tua espressione aggiunta verifica qualcos'altro. Sarebbe equivalenteWHERE id <> ALL (ARRAY[1, 2]) OR id IS NULL;
Ci sono due punti ovvi, così come i punti nell'altra risposta:
Sono esattamente equivalenti quando si utilizzano query secondarie:
SELECT * FROM table
WHERE column IN(subquery);
SELECT * FROM table
WHERE column = ANY(subquery);
D'altro canto:
Solo l' IN
operatore consente un semplice elenco:
SELECT * FROM table
WHERE column IN(… , … , …);
Presumere che siano esattamente gli stessi mi ha colto di sorpresa diverse volte quando ANY
ho dimenticato che non funziona con le liste.