web-dev-qa-db-fra.com

Oracle: '= ANY ()' contre 'IN ()'

Je suis juste tombé sur quelque chose dans Oracle SQL (je ne sais pas si c'est dans d'autres), qui m'intéresse. Je demande ici en tant que wiki, car il est difficile d'essayer de rechercher des symboles dans Google ...

Je viens de découvrir que lors de la vérification d'une valeur par rapport à un ensemble de valeurs, vous pouvez le faire

WHERE x = ANY (a, b, c)

Contrairement à l'habituel

WHERE x IN (a, b, c)

Je suis donc curieux, quel est le raisonnement pour ces deux syntaxes? Est-ce un standard et un autre une étrange syntaxe Oracle? Ou sont-ils tous les deux standard? Et y a-t-il une préférence de l'un par rapport à l'autre pour des raisons de performances, ou?

Juste curieux de savoir ce que n'importe qui peut me dire à propos de cette syntaxe '= ANY'. CheerZ!

50
eidylon

ANY (ou son synonyme SOME) est un sucre de syntaxe pour EXISTS avec une simple corrélation:

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

est le même que:

SELECT  *
FROM    mytable m
WHERE   EXISTS
        (
        SELECT  NULL
        FROM    othertable o
        WHERE   m.x <= o.y
        )

Avec la condition d'égalité sur un champ non nul, elle devient similaire à IN.

Toutes les principales bases de données, y compris SQL Server, MySQL et PostgreSQL, prennent en charge ce mot clé.

33
Quassnoi
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() - less than maximum
>ANY() - more than minimum
=ANY() - equivalent to IN
>ALL() - more than the maximum
<ALL() - less than the minimum

par exemple:

Trouvez les employés qui gagnent le même salaire que le salaire minimum pour chaque département:

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

Employés qui ne sont pas des programmeurs informatiques et dont le salaire est inférieur à celui de n'importe quel programmeur informatique:

SELECT employee_id, last_name, salary, job_id
FROM employees
WHERE salary <ANY
                (SELECT salary
                 FROM employees
                 WHERE job_id = 'IT_PROG')
AND job_id <> 'IT_PROG';

Employés dont le salaire est inférieur au salaire de tous les employés avec un ID de travail IT_PROG et dont l'emploi n'est pas IT_PROG:

SELECT employee_id,last_name, salary,job_id
FROM employees
WHERE salary <ALL
                (SELECT salary
                 FROM employees
                 WHERE job_id = 'IT_PROG')
AND job_id <> 'IT_PROG';

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

J'espère que ça aide. -Noorin Fatima

19
noorin fatima

Pour le dire simplement et en citant le "Mastering Oracle SQL" d'O'Reilly:

"L'utilisation de IN avec une sous-requête est fonctionnellement équivalente à l'utilisation de N'IMPORTE QUEL, et renvoie VRAI si une correspondance est trouvée dans l'ensemble renvoyé par la sous-requête."

"Nous pensons que vous conviendrez que IN est plus intuitif que TOUT, c'est pourquoi IN est presque toujours utilisé dans de telles situations."

J'espère que cela clarifie votre question sur TOUT vs IN.

16
CraigH

Je crois que ce que vous recherchez est le suivant:

http://download-west.Oracle.com/docs/cd/B10501_01/server.920/a96533/opt_ops.htm#1005298 (Lien trouvé sur Blog d'Eddie Awad ) Pour résumer ici:

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

se transforme en

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

tandis que

salary > ANY (:first_sal, :second_sal)

se transforme en

salary > :first_sal OR salary > :second_sal

L'optimiseur transforme une condition qui utilise l'opérateur ANY ou SOME suivi d'une sous-requête en une condition contenant l'opérateur EXISTS et une sous-requête corrélée

9
Sean Vieira

La syntaxe ANY vous permet d'écrire des choses comme

WHERE x > ANY(a, b, c)

ou événement

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

Je ne sais pas s'il y a réellement quelqu'un sur la planète qui utilise TOUT (et son frère TOUS).

6
erikkallen

Un rapide Google a trouvé ceci http://theopensourcery.com/sqlanysomeall.htm

Any vous permet d'utiliser un opérateur autre que =, dans la plupart des autres cas (cas particuliers pour les valeurs nulles), il agit comme IN. Vous pouvez considérer IN comme TOUT avec l'opérateur =.

5
Hogan

Ceci est une norme. Les états standard SQL 1992

8.4 <en prédicat>

[...]

<in predicate> ::=
    <row value constructor>
      [ NOT ] IN <in predicate value>

[...]

2) Soit RVC le <constructeur de la valeur de ligne> et IPV le <en valeur de prédicat>.

[...]

4) L'expression

  RVC IN IPV

est équivalent à

  RVC = ANY IPV  

Donc en fait, le <in predicate> la définition du comportement est basée sur le 8.7 <quantified comparison predicate>. En d'autres termes, Oracle implémente correctement la norme SQL ici

1
Lukas Eder

Peut-être que l'un des articles liés le souligne, mais n'est-il pas vrai que lorsque vous recherchez une correspondance (=), les deux retournent la même chose. Cependant, si vous recherchez une gamme de réponses (>, <, etc.), vous ne pouvez pas utiliser "IN" et devez utiliser "ANY" ...

Je suis un nouveau, pardonne-moi si j'ai raté quelque chose d'évident ...

1
Dave

MySql efface TOUT dans sa documentation:

Le mot clé ANY, qui doit suivre un opérateur de comparaison, signifie "retourner VRAI si la comparaison est VRAIE pour TOUTES les valeurs de la colonne que la sous-requête renvoie". Par exemple:

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

Supposons qu'il existe une ligne dans le tableau t1 contenant (10). L'expression est TRUE si la table t2 contient (21,14,7) car il y a une valeur 7 dans t2 qui est inférieure à 10. L'expression est FALSE si la table t2 contient (20,10) ou si la table t2 est vide. L'expression est inconnue (c'est-à-dire NULL) si la table t2 contient (NULL, NULL, NULL).

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

Apprendre également SQL par Alan Beaulieu déclare ce qui suit:

Bien que la plupart des gens préfèrent utiliser IN, utiliser = ANY équivaut à utiliser l'opérateur IN.

1
Robert Rocha