Oracle: ‘= ANY ()’ vs. ‘IN ()’

Mi sono imbattuto in qualcosa in ORACLE SQL (non sono sicuro che sia in altri), di cui sono curioso. Sto chiedendo qui come wiki, dal momento che è difficile provare a cercare simboli in google …

Ho appena scoperto che quando si controlla un valore rispetto a un insieme di valori che si possono fare

WHERE x = ANY (a, b, c) 

Al contrario del solito

 WHERE x IN (a, b, c) 

Quindi sono curioso, qual è il ragionamento per queste due syntax? C’è uno standard e una syntax di Oracle strano? O sono entrambi standard? E c’è una preferenza di uno sull’altro per motivi di prestazioni, o?

È solo curioso di sapere cosa mi può dire di quella syntax ‘= QUALSIASI’. Cheerz!

ANY (o il suo sinonimo SOME ) è uno zucchero di syntax per EXISTS con una semplice correlazione:

 SELECT * FROM mytable WHERE x <= ANY ( SELECT y FROM othertable ) 

equivale a:

 SELECT * FROM mytable m WHERE EXISTS ( SELECT NULL FROM othertable o WHERE mx <= oy ) 

Con la condizione di uguaglianza su un campo non nullable, diventa simile a IN .

Tutti i principali database, tra cui SQL Server , MySQL e PostgreSQL , supportano questa parola chiave.

 IN- Equal to any member in the list ANY- Compare value to **each** value returned by the subquery ALL- Compare value to **EVERY** value returned by the subquery ANY() - more than minimum =ANY() - equivalent to IN >ALL() - more than the maximum  

per esempio:

Trova i dipendenti che guadagnano lo stesso stipendio del salario minimo per ciascun dipartimento:

 SELECT last_name, salary,department_id FROM employees WHERE salary IN (SELECT MIN(salary) FROM employees GROUP BY department_id); 

Dipendenti che non sono programmatori IT e il cui stipendio è inferiore a quello di qualsiasi programmatore IT:

 SELECT employee_id, last_name, salary, job_id FROM employees WHERE salary  'IT_PROG'; 

Dipendenti il ​​cui stipendio è inferiore allo stipendio di tutti i dipendenti con un ID lavoro IT_PROG e il cui lavoro non è IT_PROG:

 SELECT employee_id,last_name, salary,job_id FROM employees WHERE salary  'IT_PROG'; 

....................

Spero che sia d'aiuto. -Noorin Fatima

Per dirla semplicemente e citando da O’Reilly “Mastering Oracle SQL”:

“L’uso di IN con una sottoquery è funzionalmente equivalente all’utilizzo di ANY e restituisce VERO se viene trovata una corrispondenza nell’insieme restituito dalla sottoquery.”

“Pensiamo che sarete d’accordo sul fatto che IN sia più intuitivo di QUALSIASI, ed è per questo che IN è quasi sempre usato in queste situazioni.”

Spero che chiarisca la tua domanda su ANY vs IN.

Credo che quello che stai cercando sia questo:

http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96533/opt_ops.htm#1005298 (Link trovato sul blog di Eddie Awad ) Per riassumere qui:

last_name IN ('SMITH', 'KING', 'JONES')

viene trasformato in

last_name = 'SMITH' OR last_name = 'KING' OR last_name = 'JONES'

mentre

salary > ANY (:first_sal, :second_sal)

viene trasformato in

salary > :first_sal OR salary > :second_sal

L’ottimizzatore trasforma una condizione che utilizza l’operatore ANY o SOME seguito da una sottoquery in una condizione contenente l’operatore EXISTS e una sottoquery correlata

La syntax ANY ti permette di scrivere cose come

 WHERE x > ANY(a, b, c) 

o evento

 WHERE x > ANY(SELECT ... FROM ...) 

Non sono sicuro che ci sia qualcuno sul pianeta che usa QUALSIASI (e suo fratello TUTTI).

Un rapido google ha trovato questo http://theopensourcery.com/sqlanysomeall.htm

Qualsiasi consente di utilizzare un operatore diverso da =, nella maggior parte degli altri (casi speciali per null) si comporta come IN. Puoi pensare a IN come QUALSIASI con l’operatore =.

Questo è uno standard. Lo standard SQL 1992 afferma

8.4

[…]

  ::=  [ NOT ] IN  

[…]

2) Lascia che RVC sia il e consenti a IPV di .

[…]

4) L’espressione

  RVC IN IPV 

è equivalente a

  RVC = ANY IPV 

Pertanto, la definizione del comportamento si basa sul 8.7 . In altre parole, Oracle implementa correttamente lo standard SQL qui

Forse uno degli articoli collegati lo mette in evidenza, ma non è vero che quando si cerca una corrispondenza (=) i due restituiscono la stessa cosa. Tuttavia, se stai cercando una gamma di risposte (>, <, ecc.) Non puoi usare "IN" e dovresti usare "ANY" ...

Sono un newb, perdonami se ho perso qualcosa di ovvio …

MySql cancella QUALSIASI nella sua documentazione abbastanza bene:

La parola chiave ANY, che deve seguire un operatore di confronto, significa “restituisce TRUE se il confronto è VERO per QUALSIASI dei valori nella colonna restituiti dalla sottoquery”. Ad esempio:

SELECT s1 FROM t1 WHERE s1 > ANY (SELECT s1 FROM t2);

Supponiamo che ci sia una riga nella tabella t1 che contiene (10). L’espressione è TRUE se la tabella t2 contiene (21,14,7) perché c’è un valore 7 in t2 che è minore di 10. L’espressione è FALSE se la tabella t2 contiene (20,10) o se la tabella t2 è vuota. L’espressione è sconosciuta (ovvero NULL) se la tabella t2 contiene (NULL, NULL, NULL).

https://dev.mysql.com/doc/refman/5.5/en/any-in-some-subqueries.html

Anche Learning SQL di Alan Beaulieu afferma quanto segue:

Sebbene molte persone preferiscano usare IN, usare = ANY equivale a usare l’operatore IN.