Qual è la differenza tra INe ANYoperator in PostgreSQL?
Il meccanismo di funzionamento di entrambi sembra essere lo stesso. Qualcuno può spiegarlo con un esempio?
Qual è la differenza tra INe ANYoperator in PostgreSQL?
Il meccanismo di funzionamento di entrambi sembra essere lo stesso. Qualcuno può spiegarlo con un esempio?
Risposte:
(Né INné 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 = ANYprendere un set , come dimostrato qui:
Ma la seconda variante di ciascuna non è equivalente all'altra. La seconda variante del ANYcostrutto accetta un array (deve essere un tipo di array effettivo), mentre la seconda variante di INaccetta 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 coninANY è più versatileLa ANYstruttura è 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 idtrova 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 NULLnon superano nessuna di queste espressioni. Per includere NULLvalori 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.
ANYpuò 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.)
NULLvalori? Funzionerebbe WHERE id = ANY (ARRAY[1, 2]) OR id IS NULL;altrettanto bene?
(id = ...) IS NOT TRUEfunziona perché id = ...valuta solo TRUEse esiste una corrispondenza effettiva. Risultati FALSEo NULLsupera 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' INoperatore consente un semplice elenco:
SELECT * FROM table
WHERE column IN(… , … , …);Presumere che siano esattamente gli stessi mi ha colto di sorpresa diverse volte quando ANYho dimenticato che non funziona con le liste.