Catégories :

Syntaxe de requête

WHERE

La clause WHERE spécifie une condition qui correspond à un sous-ensemble de lignes. Vous pouvez utiliser la clause WHERE pour :

Syntaxe

...
WHERE <predicate>
[ ... ]
prédicat

Une expression booléenne. L’expression peut inclure des opérateurs logiques, tels que AND, OR et NOT.

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éer FULL OUTER JOIN. Vous ne pouvez créer que LEFT OUTER JOIN et RIGHT 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).