カテゴリ:

クエリ構文

WHERE

WHERE 句は、行のサブセットに一致する条件を指定します。 WHERE 句を使用して次のことができます。

  • SELECT ステートメントの FROM 句の結果をフィルタリングします。

  • UPDATEMERGE 、または DELETE で操作する行を指定します

構文

...
WHERE <predicate>
[ ... ]
述語

ブール式。式には、 ANDORNOT などの 論理演算子 を含めることができます。

使用上の注意

  • WHERE 句の述語は、 FROM 句の後に評価されるかのように動作します(ただし、結果に影響しない場合、オプティマイザは述語を並べ替えることができます)。例えば、WHERE 句の述語が FROM 句の外部結合に参加しているテーブルの列を参照する場合、結合から返された行(NULLs が埋め込まれる可能性があります)をフィルターが操作します。

  • NULLs を評価する可能性のある式を作成するときは注意してください。

    • ほとんどの場合、ブール式 NULL = NULL は TRUE ではなく NULL を返します。

    • WHERE 句で、式が NULL と評価された場合、その式の行は結果セットから削除されます(つまり、フィルターで除外されます)。

WHERE 句で結合します

WHERE 句は主にフィルタリング用ですが、 WHERE 句を使用してさまざまな種類の結合を表現することもできます。結合の概念については、 JOIN(結合)の操作 を参照してください。

次のクエリは内部結合を作成します。

SELECT t1.c1, t2.c2
    FROM t1, t2
    WHERE t1.c1 = t2.c2
    ORDER BY 1,2;

結合は、 WHERE 句に結合条件を含めることにより、 FROM 句での指定に加え、またはその代わりに、 WHERE 句で表現できます。

次の2つの同義のクエリは、 FROM または 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;

外部結合は、 (+) 構文を使用して WHERE 句で指定できます。 (+) を使用して外部結合を指定するには、結合の NULL 拡張テーブルの列に WHERE 句の (+) の注釈を付けます。

次の2つの同義のクエリは、外部結合を FROM 句または WHERE 句で表現する方法を示しています。

SELECT c1, c2
FROM t1 LEFT OUTER JOIN t2
        ON c1 = c2;

SELECT c1, c2
FROM t1, t2
WHERE c1 = c2(+);

注釈

(+) 注釈を表示できる場所には多くの制限があります。 FROM 句の外部結合のほうが表現性に優れています。Snowflakeは、既にその表記法を使用しているコードを移植する場合にのみ (+) 表記法を使用することを推奨しています。新しいコードではその表記を避ける必要があります。

制限事項は次のとおりです。

  • FULL OUTER JOIN を作成するために (+) 表記を使用することはできません。作成できるのは LEFT OUTER JOINRIGHT OUTER JOIN のみです。

WHERE 句での結合のサポートは、主に FROM ... ON ... 構文を使用しない古いクエリとの下位互換性のためです。Snowflake は、結合を使用して新しいクエリを作成するときに FROM ... ON ... を使用することをお勧めします。詳細については、 JOIN をご参照ください。

フィルタリングの簡単な例

以下に、 WHERE 句の簡単な使用例を示します。

SELECT * FROM invoices
  WHERE invoice_date < '2018-01-01';

SELECT * FROM invoices
  WHERE invoice_date < '2018-01-01' AND paid = False;

この例では、サブクエリを使用して、請求額が平均を下回るすべての請求書を表示します。

SELECT * FROM invoices
  WHERE amount < (SELECT AVG(amount) FROM invoices);

WHERE 句での結合の実行

WHERE 句で結合を指定するには、結合するテーブルを FROM clause でリストし、テーブルをコンマで区切ります。次の例に示すように、 WHERE 句で結合条件をフィルターとして指定します。

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 |
+------+------+

注釈

カンマ演算子は、 INNER JOIN の古い構文です。次のステートメントは、新しい構文を使用して結合を実行するための推奨される方法を示しています。以下のクエリは、上記のクエリと同等です。

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 |
+------+------+

この次のセクションでは、3-テーブル結合を示し、0、1、または 2 (+) 外部結合演算子との動作の違いを示します。

クエリを実行する前に、結合で使用するテーブルを作成してロードします。

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)
    ;

3方向の内部結合を実行します。これは (+) (または OUTER キーワード)を使用しないため、内部結合です。出力には、部門、プロジェクト、および従業員が存在する行のみが含まれます。

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       |
+------------------+-------------------------------+------------------+

外部結合を実行します。これは、 (+) を使用して2番目の結合を外部結合にするという ` を除いて、前のステートメント :emph:` に似ています。その結果、ある部門が出力に含まれている場合、それらのプロジェクトに従業員がいない場合でも、その部門のすべてのプロジェクトが含まれます。

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             |
+----------------------------------+-------------------------------+------------------+

2 つの外部結合を実行します。これは、前のステートメント を除いて と同じですが、これは (+) を使用して両方の結合を外部結合にします。その結果、(プロジェクトまたは従業員がまだいない場合でも)すべての部門が含まれ、(まだ従業員がいない場合でも)部門に関連付けられているすべてのプロジェクトが含まれます。出力には、部門のないプロジェクトが含まれていないことに注意してください。

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             |
+----------------------------------------------+-------------------------------+------------------+

(ただし、Snowflake では、 WHERE 句で (+) 演算子を使用するのではなく、 FROM 句で OUTER キーワードを使用することをお勧めします。)