- Catégories :
WHERE¶
La clause WHERE
spécifie une condition qui correspond à un sous-ensemble de lignes. Vous pouvez utiliser la clause WHERE
pour :
Filtrer le résultat de la clause FROM dans une instruction SELECT.
Préciser les lignes à traiter dans un UPDATE, MERGE, ou DELETE
Syntaxe¶
...
WHERE <predicate>
[ ... ]
prédicat
Une expression booléenne. L’expression peut inclure des opérateurs logiques, tels que
AND
,OR
etNOT
.
Notes sur l’utilisation¶
Les prédicats de la clause WHERE se comportent comme s’ils étaient évalués après la clause FROM (bien que l’optimiseur puisse réorganiser les prédicats s’il n’y a pas d’incidence sur les résultats). Par exemple, si un prédicat de la clause WHERE fait référence aux colonnes d’une table participant à une jointure externe de la clause FROM, le filtre agit sur les lignes renvoyées par la jointure (pouvant être complétées avec des NULLs).
Faites attention lorsque vous créez des expressions qui pourraient correspondre à des valeurs NULLs.
Dans la plupart des contextes, l’expression booléenne
NULL = NULL
renvoie NULL et non TRUE.Dans une clause
WHERE
, si une expression correspond à NULL, la ligne correspondant à cette expression est supprimée du jeu de résultats (c’est-à-dire qu’elle est filtrée).
Jointures dans la clause WHERE¶
Bien que la clause WHERE
soit principalement destinée au filtrage, la clause WHERE
peut également être utilisée pour exprimer de nombreux types de jointures. Pour des informations conceptuelles sur les jointures, voir Utilisation des jointures (ou jonctions).
La requête suivante crée une jointure intérieure :
SELECT t1.c1, t2.c2
FROM t1, t2
WHERE t1.c1 = t2.c2
ORDER BY 1,2;
Les jointures peuvent être exprimées dans la clause WHERE, en plus ou au lieu de les spécifier dans la clause FROM, en incluant des conditions de jointure dans la clause WHERE.
Les deux requêtes équivalentes suivantes montrent comment exprimer une jointure dans les clauses FROM ou WHERE :
SELECT c1, c2 FROM t1 INNER JOIN t2 ON c1 = c2 ORDER BY 1,2; SELECT c1, c2 FROM t1, t2 WHERE c1 = c2 ORDER BY 1,2;
Les jointures externes peuvent être spécifiées dans la clause WHERE à l’aide de la syntaxe (+)
. Pour spécifier une jointure externe à l’aide de (+)
, les colonnes de la table NULL enrichie de la jointure sont annotées avec le (+)
dans la clause WHERE.
Les deux requêtes équivalentes suivantes montrent comment une jointure externe peut être exprimée dans la clause FROM ou WHERE :
SELECT c1, c2 FROM t1 LEFT OUTER JOIN t2 ON c1 = c2; SELECT c1, c2 FROM t1, t2 WHERE c1 = c2(+);Note
Il existe de nombreuses restrictions quant à l’emplacement où l’annotation
(+)
peut apparaître. Les jointures externes de la clause FROM sont plus expressives. Snowflake suggère d’utiliser la notation(+)
uniquement lors du transfert de code utilisant déjà cette notation. Le nouveau code devrait éviter cette notation.Les restrictions comprennent :
Vous ne pouvez pas utiliser la notation
(+)
pour créerFULL OUTER JOIN
. Vous ne pouvez créer queLEFT OUTER JOIN
etRIGHT OUTER JOIN
.
La prise en charge des jointures dans la clause WHERE
est principalement destinée à assurer la compatibilité ascendante avec les anciennes requêtes qui n’utilisent pas la syntaxe FROM ... ON ...
. Snowflake recommande d’utiliser FROM ... ON ...
lors de l’écriture de nouvelles requêtes avec des jointures. Pour plus de détails, voir JOIN.
Exemples¶
Exemples simples de filtrage¶
Les exemples suivants montrent quelques utilisations simples de la clause WHERE :
SELECT * FROM invoices WHERE invoice_date < '2018-01-01'; SELECT * FROM invoices WHERE invoice_date < '2018-01-01' AND paid = False;
Cet exemple utilise une sous-requête et affiche toutes les factures dont le montant de facturation est inférieur à la moyenne :
SELECT * FROM invoices WHERE amount < (SELECT AVG(amount) FROM invoices);
Exécuter des jointures dans la clause WHERE
¶
Pour spécifier une jointure dans la clause WHERE
, énumérez les tables à joindre dans FROM clause
, en séparant les tables par une virgule. Spécifiez la condition de jointure comme un filtre dans la clause WHERE
, comme indiqué dans l’exemple suivant :
SELECT t1.col1, t2.col1 FROM t1, t2 WHERE t2.col1 = t1.col1 ORDER BY 1, 2; +------+------+ | COL1 | COL1 | |------+------| | 2 | 2 | | 2 | 2 | | 3 | 3 | +------+------+
Note
L’opérateur virgule est l’ancienne syntaxe de INNER JOIN
. L’instruction suivante montre la façon recommandée de réaliser une jointure en utilisant une syntaxe plus récente. La requête ci-dessous est équivalente à la requête ci-dessus :
SELECT t1.col1, t2.col1 FROM t1 JOIN t2 ON t2.col1 = t1.col1 ORDER BY 1, 2; +------+------+ | COL1 | COL1 | |------+------| | 2 | 2 | | 2 | 2 | | 3 | 3 | +------+------+
La section suivante montre les jointures de table 3 et montre la différence de comportement avec les opérateurs de jointures extérieures 0, 1 ou 2 (+)
.
Avant d’exécuter les requêtes, créez et chargez les tables à utiliser dans les jointures :
create table departments ( department_ID INTEGER, department_name VARCHAR, location VARCHAR ); insert into departments (department_id, department_name, location) values (10, 'CUSTOMER SUPPORT', 'CHICAGO'), (40, 'RESEARCH', 'BOSTON'), (80, 'Department with no employees yet', 'CHICAGO'), (90, 'Department with no projects or employees yet', 'EREHWON') ; create table projects ( project_id integer, project_name varchar, department_id integer ); insert into projects (project_id, project_name, department_id) values (4000, 'Detect fake product reviews', 40), (4001, 'Detect false insurance claims', 10), (9000, 'Project with no employees yet', 80), (9099, 'Project with no department or employees yet', NULL) ; create table employees ( employee_ID INTEGER, employee_name VARCHAR, department_id INTEGER, project_id INTEGER ); insert into employees (employee_id, employee_name, department_id, project_id) values (1012, 'May Aidez', 10, NULL), (1040, 'Devi Nobel', 40, 4000), (1041, 'Alfred Mendeleev', 40, 4001) ;Exécutez une jointure intérieure à 3 voies. Ceci n’utilise pas
(+)
(ou le mot-clé OUTER) et est donc une jointure intérieure. La sortie ne comprend que les lignes pour lesquelles il existe un département, un projet et un employé :SELECT d.department_name, p.project_name, e.employee_name FROM departments d, projects p, employees e WHERE p.department_id = d.department_id AND e.project_id = p.project_id ORDER BY d.department_id, p.project_id, e.employee_id; +------------------+-------------------------------+------------------+ | DEPARTMENT_NAME | PROJECT_NAME | EMPLOYEE_NAME | |------------------+-------------------------------+------------------| | CUSTOMER SUPPORT | Detect false insurance claims | Alfred Mendeleev | | RESEARCH | Detect fake product reviews | Devi Nobel | +------------------+-------------------------------+------------------+Effectuer une jointure extérieure. Cela est similaire à l’instruction précédente sauf que celle-ci utilise
(+)
pour faire de la deuxième jointure une jointure extérieure. L’effet est que si un département est inclus dans la sortie, alors tous les projets de ce département sont inclus, même si ces projets n’ont pas d’employés :SELECT d.department_name, p.project_name, e.employee_name FROM departments d, projects p, employees e WHERE p.department_id = d.department_id AND e.project_id(+) = p.project_id ORDER BY d.department_id, p.project_id, e.employee_id; +----------------------------------+-------------------------------+------------------+ | DEPARTMENT_NAME | PROJECT_NAME | EMPLOYEE_NAME | |----------------------------------+-------------------------------+------------------| | CUSTOMER SUPPORT | Detect false insurance claims | Alfred Mendeleev | | RESEARCH | Detect fake product reviews | Devi Nobel | | Department with no employees yet | Project with no employees yet | NULL | +----------------------------------+-------------------------------+------------------+Effectuer deux jointures extérieures. Cela est similaire à l’instruction précédente sauf que celle-ci utilise
(+)
pour faire des deux jointures des jointures extérieures. L’effet est que tous les départements sont inclus (même s’ils n’ont pas encore de projets ou d’employés) et tous les projets associés aux départements sont inclus (même s’ils n’ont pas encore d’employés). Notez que la sortie exclut les projets qui n’ont pas de département.SELECT d.department_name, p.project_name, e.employee_name FROM departments d, projects p, employees e WHERE p.department_id(+) = d.department_id AND e.project_id(+) = p.project_id ORDER BY d.department_id, p.project_id, e.employee_id; +----------------------------------------------+-------------------------------+------------------+ | DEPARTMENT_NAME | PROJECT_NAME | EMPLOYEE_NAME | |----------------------------------------------+-------------------------------+------------------| | CUSTOMER SUPPORT | Detect false insurance claims | Alfred Mendeleev | | RESEARCH | Detect fake product reviews | Devi Nobel | | Department with no employees yet | Project with no employees yet | NULL | | Department with no projects or employees yet | NULL | NULL | +----------------------------------------------+-------------------------------+------------------+
(N’oubliez pas, cependant, que Snowflake recommande d’utiliser le mot-clé OUTER
dans la clause FROM
plutôt que d’utiliser l’opérateur (+)
dans la clause WHERE
).