SELECT

SELECT ステートメントとして、または他のステートメント内の句として使用できます。

  • ステートメントとして、 SELECT ステートメントは最も一般的に実行される SQL ステートメントで、データベースをクエリし、行のセットを取得します。

  • 句として、 SELECT はクエリによって返される列のセットを定義します。

こちらもご参照ください。

クエリ構文

構文

次のセクションでは、このコマンドの構文について説明します。

すべての列の選択

[ ... ]
SELECT [ { ALL | DISTINCT } ]
       [ TOP <n> ]
       [{<object_name>|<alias>}.]*

       [ ILIKE '<pattern>' ]

       [ EXCLUDE
         {
           <col_name> | ( <col_name>, <col_name>, ... )
         }
       ]

       [ REPLACE
         {
           ( <expr> AS <col_name> [ , <expr> AS <col_name>, ... ] )
         }
       ]

       [ RENAME
         {
           <col_name> AS <col_alias>
           | ( <col_name> AS <col_alias>, <col_name> AS <col_alias>, ... )
         }
       ]
Copy

SELECT * の後に以下のキーワードの組み合わせを指定できます。キーワードは以下の順番にする必要があります。

SELECT * ILIKE ... REPLACE ...
Copy
SELECT * ILIKE ... RENAME ...
Copy
SELECT * ILIKE ... REPLACE ... RENAME ...
Copy
SELECT * EXCLUDE ... REPLACE ...
Copy
SELECT * EXCLUDE ... RENAME ...
Copy
SELECT * EXCLUDE ... REPLACE ... RENAME ...
Copy
SELECT * REPLACE ... RENAME ...
Copy

特定の列の選択

[ ... ]
SELECT [ { ALL | DISTINCT } ]
       [ TOP <n> ]
       {
         [{<object_name>|<alias>}.]<col_name>
         | [{<object_name>|<alias>}.]$<col_position>
         | <expr>
       }
       [ [ AS ] <col_alias> ]
       [ , ... ]
[ ... ]
Copy

ステートメントとしての SELECT およびステートメント内の他の句の詳細については、 クエリ構文 をご参照ください。

パラメーター

ALL | DISTINCT

結果セットで重複排除を実行するかどうかを指定します。

  • ALL には、結果セットのすべての値が含まれます。

  • DISTINCT は、結果セットから重複した値を削除します。

デフォルト: ALL

TOP n

返される結果の最大数を指定します。 TOP <n> をご参照ください。

object_name または . alias

FROM 句で定義されているオブジェクト識別子またはオブジェクトエイリアスを指定します。

*

アスタリスクは、指定されたオブジェクトのすべての列、または * がオブジェクト名またはエイリアスで修飾されていない場合、すべてのオブジェクトのすべての列を出力に含めることを示す略記です。

* を指定する場合、 ILIKEEXCLUDEREPLACE、および RENAME も指定できます。

ILIKE 'pattern'

pattern と一致する列のみが結果に含まれるように指定します。

pattern で、次の SQL ワイルドカードを使用できます。

  • 任意の1文字で一致させる場合は、アンダースコア(_)を使用します。

  • ゼロ個以上の文字のシーケンスで一致させる場合は、パーセント記号(%)を使用します。

列名内の任意の場所でシーケンスを一致させる場合は、パターンの最初と最後に % を使用します。

一致では大文字と小文字を区別しません。

指定されたパターンに一致する列がない場合は、コンパイルエラーが発生します(001080 (42601): ... SELECT with no columns)。

EXCLUDE col_name . EXCLUDE (col_name, col_name, ...)

結果から除外する列を指定します。

複数のテーブルから選択する場合は、 SELECT table_name.* を使用して特定のテーブルからすべての列を選択することを指定し、 EXCLUDE に修飾されていない列名を指定します。例:

SELECT table_a.* EXCLUDE column_in_table_a ,
  table_b.* EXCLUDE column_in_table_b
  ...
Copy
REPLACE (expr AS col_name [ , expr AS col_name, ...] )

col_name の値を評価式 expr の値で置き換えます。

たとえば、文字列 'DEPT-'department_id 列にある各値に追加するには、

SELECT REPLACE ('DEPT-' || department_id AS department_id) ...
Copy

col_name の場合:

  • 列が存在する必要があり、 ILIKE または EXCEPT によってフィルター処理することはできません。

  • 置換リストで同じ列を複数回指定することはできません。

  • 列が複数のテーブルにある場合(例: 結合の両方のテーブルにある場合)、ステートメントは「あいまいな列」エラーで失敗します。

expr は、単一の値として評価される必要があります。

RENAME col_name AS col_alias . RENAME (col_name AS col_alias, col_name AS col_alias, ...)

結果で使用される列のエイリアスを指定します。

複数のテーブルから選択する場合は、 SELECT table_name.* を使用して特定のテーブルからすべての列を選択することを指定し、 RENAME に修飾されていない列名を指定します。例:

SELECT table_a.* RENAME column_in_table_a AS col_alias_a,
  table_b.* RENAME column_in_table_b AS col_alias_b
  ...
Copy

注釈

SELECT * の後にキーワードの組み合わせを指定する場合は、

  • ILIKEEXCLUDE の両方を指定することはできません。

  • RENAME または REPLACEEXCLUDE を指定した場合は、

    • RENAME または REPLACE の前に EXCLUDE を指定する必要があります。

      SELECT * EXCLUDE col_a RENAME col_b AS alias_b ...
      
      Copy
      SELECT * EXCLUDE employee_id REPLACE ('DEPT-' || department_id AS department_id) ...
      
      Copy
    • EXCLUDERENAME で同じ列を指定することはできません。

  • RENAME または REPLACEILIKE を指定する場合は、最初に ILIKE を指定する必要があります。

    SELECT * ILIKE '%id%' RENAME department_id AS department ...
    
    Copy
    SELECT * ILIKE '%id%' REPLACE ('DEPT-' || department_id AS department_id) ...
    
    Copy
  • REPLACERENAME を指定した場合は、

    • 最初に REPLACE を指定する必要があります。

      SELECT * REPLACE ('DEPT-' || department_id AS department_id) RENAME employee_id as employee ...
      
      Copy
    • REPLACERENAME で同じ列名を指定できます。

      SELECT * REPLACE ('DEPT-' || department_id AS department_id) RENAME department_id as department ...
      
      Copy
col_name

FROM 句で定義されている列識別子を指定します。

$col_position

FROM 句で定義されている列の位置(1ベース)を指定します。列がテーブルから参照される場合、この数はテーブル内の列の最大数を超えることはできません。

expr

特定の行の特定の値に評価される数式などの式を指定します。

[ AS ] col_alias

結果の式に割り当てられる列エイリアスを指定します。これは、最上位の SELECT リストでの表示名、およびインラインビューでの列名として使用されます。

クエリで参照される他の列の名前と同じ列エイリアスを割り当てないでください。例えば、 prod_idproduct_id という名前の列を選択している場合、 prod_idproduct_id というエイリアスにしないでください。 エラーケース: 別の列名に一致するエイリアスの指定 をご参照ください。

FORUPDATE 句の使用

オプションの FOR UPDATE 句を使用して、将来の更新のために結果をロックします。

SELECT ...
  FROM ...
  [ ... ]
  FOR UPDATE [ NOWAIT | WAIT <wait_time> ]
Copy

パラメーター

WAIT

このステートメントがロックを取得するまでの最大待機時間(秒)を整数で指定します。

使用上の注意

注釈

ハイブリッドテーブルは READ COMMITTED 分離レベルをサポートするため、 FOR UPDATE 句は読み取りの安定性を保証できません。

  • ID のみを持つテーブル T は2つのタプル、5と10で始まります。

  • トランザクション T1SELECT * FROM T WHERE ID < 20 FOR UPDATE は2つのタプル、5と10を返し、それらをロックします。

    • 別のトランザクション T2 からの DELETE FROM T WHERE ID = 5 は、 T1 が完了(コミットまたはロールバック)するまで待機する必要があります。

  • しかし、別のトランザクション T3INSERT INTO T VALUES 12 は完了することができ、 T1 の後続の SELECT * FROM T WHERE ID < 20 は3つのタプル、5、10、12になります。

使用上の注意

  • エイリアスと識別子はデフォルトで大文字と小文字を区別しません。大文字と小文字を保持するには、二重引用符(")で囲みます。詳細については、 オブジェクト識別子 をご参照ください。

  • ORDER BY 句がない場合、 SELECT によって返される結果は順序付けられていないセットです。同じテーブルに対して同じクエリを繰り返し実行すると、毎回異なる出力順序になる可能性があります。順序が重要な場合は、 ORDER BY 句を使用します。

  • SELECT は、独立したステートメントとしてだけでなく、たとえば、 INSERT INTO ... SELECT ...; など、他のステートメントにある句の一部としても使用できます。SELECT は、ステートメント内の サブクエリ でも使用できます。

  • 多くの場合、同じクエリの他の部分(JOIN、 FROM、 WHERE、 GROUP BY、他の列式など)で式(つまり、 expr AS col_alias)の列エイリアスを使用する場合、式は1回だけ評価されます。

    ただし、場合によっては、式が複数回評価される可能性があり、その結果、同じクエリの異なる部分で使用されるエイリアスの値が異なる可能性があることに注意してください。

いくつかの簡単な例を以下に示します。

クエリ構文 の詳細な説明を含む、ドキュメントの他の部分には多くの追加例が含まれています。

イベントテーブル(スキーマがSnowflakeによって事前定義されている)のクエリに関連する例については、 ログされたメッセージデータへのアクセストレースデータへのアクセス をご参照ください。

例に対するデータの設定

以下のクエリのいくつかでは、次のテーブルとデータを使用します。

CREATE TABLE employee_table (
    employee_ID INTEGER,
    last_name VARCHAR,
    first_name VARCHAR,
    department_ID INTEGER
    );

CREATE TABLE department_table (
    department_ID INTEGER,
    department_name VARCHAR
    );
Copy
INSERT INTO employee_table (employee_ID, last_name, first_name, department_ID) VALUES
    (101, 'Montgomery', 'Pat', 1),
    (102, 'Levine', 'Terry', 2),
    (103, 'Comstock', 'Dana', 2);

INSERT INTO department_table (department_ID, department_name) VALUES
    (1, 'Engineering'),
    (2, 'Customer Support'),
    (3, 'Finance');
Copy

すべての列を選択する例(SELECT *)

テーブル内にあるすべての列の選択

この例は、 employee_table 内にあるすべての列を選択する方法を示しています。

SELECT * FROM employee_table;
Copy
+-------------+------------+------------+---------------+
| EMPLOYEE_ID | LAST_NAME  | FIRST_NAME | DEPARTMENT_ID |
|-------------+------------+------------+---------------|
|         101 | Montgomery | Pat        |             1 |
|         102 | Levine     | Terry      |             2 |
|         103 | Comstock   | Dana       |             2 |
+-------------+------------+------------+---------------+

パターンに一致する名前を持つすべての列の選択

この例は、 id を含む名前のある employee_table のすべての列を選択する方法を示しています。

SELECT * ILIKE '%id%' FROM employee_table;
Copy
+-------------+---------------+
| EMPLOYEE_ID | DEPARTMENT_ID |
|-------------+---------------|
|         101 |             1 |
|         102 |             2 |
|         103 |             2 |
+-------------+---------------+

1つの列を除くすべての列の選択

この例は、 department_id 列を除く employee_table のすべての列を選択する方法を示しています。

SELECT * EXCLUDE department_id FROM employee_table;
Copy
+-------------+------------+------------+
| EMPLOYEE_ID | LAST_NAME  | FIRST_NAME |
|-------------+------------+------------|
|         101 | Montgomery | Pat        |
|         102 | Levine     | Terry      |
|         103 | Comstock   | Dana       |
+-------------+------------+------------+

複数の列を除くすべての列の選択

この例は、 department_id 列と employee_id 列を除く employee_table のすべての列を選択する方法を示しています。

SELECT * EXCLUDE (department_id, employee_id) FROM employee_table;
Copy
+------------+------------+
| LAST_NAME  | FIRST_NAME |
|------------+------------|
| Montgomery | Pat        |
| Levine     | Terry      |
| Comstock   | Dana       |
+------------+------------+

すべての列の選択と1つの列の名前変更

次の例は、 employee_table のすべての列を選択し、 department_id 列の名前を変更する方法を示しています。

SELECT * RENAME department_id AS department FROM employee_table;
Copy
+-------------+------------+------------+------------+
| EMPLOYEE_ID | LAST_NAME  | FIRST_NAME | DEPARTMENT |
|-------------+------------+------------+------------|
|         101 | Montgomery | Pat        |          1 |
|         102 | Levine     | Terry      |          2 |
|         103 | Comstock   | Dana       |          2 |
+-------------+------------+------------+------------+

すべての列の選択と複数の列の名前変更

次の例は、 employee_table のすべての列を選択し、 department_id 列と employee_id 列の名前を変更する方法を示しています。

SELECT * RENAME (department_id AS department, employee_id AS id) FROM employee_table;
Copy
+-----+------------+------------+------------+
|  ID | LAST_NAME  | FIRST_NAME | DEPARTMENT |
|-----+------------+------------+------------|
| 101 | Montgomery | Pat        |          1 |
| 102 | Levine     | Terry      |          2 |
| 103 | Comstock   | Dana       |          2 |
+-----+------------+------------+------------+

すべての列の選択、1つの列の除外、および複数の列の名前変更

次の例は、 employee_table のすべての列を選択し、 first_name 列を除外して、 department_id 列と employee_id 列の名前を変更する方法を示しています。

SELECT * EXCLUDE first_name RENAME (department_id AS department, employee_id AS id) FROM employee_table;
Copy
+-----+------------+------------+
|  ID | LAST_NAME  | DEPARTMENT |
|-----+------------+------------|
| 101 | Montgomery |          1 |
| 102 | Levine     |          2 |
| 103 | Comstock   |          2 |
+-----+------------+------------+

パターンに一致する名前の列すべての選択および列名の変更

次の例は、 id を含む名前のある employee_table のすべての列を選択し、 department_id 列の名前を変更する方法を示しています。

SELECT * ILIKE '%id%' RENAME department_id AS department FROM employee_table;
Copy
+-------------+------------+
| EMPLOYEE_ID | DEPARTMENT |
|-------------+------------|
|         101 |          1 |
|         102 |          2 |
|         103 |          2 |
+-------------+------------+

すべての列の選択および列の値の置換

この例は、 employee_table のすべての列を選択し、 department_id 列の値を ID の前に DEPT- を追加したものと置き換える方法を示しています。

SELECT * REPLACE ('DEPT-' || department_id AS department_id) FROM employee_table;
Copy
+-------------+------------+------------+---------------+
| EMPLOYEE_ID | LAST_NAME  | FIRST_NAME | DEPARTMENT_ID |
|-------------+------------+------------+---------------|
|         101 | Montgomery | Pat        | DEPT-1        |
|         102 | Levine     | Terry      | DEPT-2        |
|         103 | Comstock   | Dana       | DEPT-2        |
+-------------+------------+------------+---------------+

すべての列の選択、列の値の置換、および列名の変更

この例は、 employee_table のすべての列を選択し、 department_id 列の値を ID の前に DEPT- を付加したものと置き換え、列の名前を変更する方法を示しています。

SELECT * REPLACE ('DEPT-' || department_id AS department_id) RENAME department_id AS department FROM employee_table;
Copy
+-------------+------------+------------+------------+
| EMPLOYEE_ID | LAST_NAME  | FIRST_NAME | DEPARTMENT |
|-------------+------------+------------+------------|
|         101 | Montgomery | Pat        | DEPT-1     |
|         102 | Levine     | Terry      | DEPT-2     |
|         103 | Comstock   | Dana       | DEPT-2     |
+-------------+------------+------------+------------+

パターンに一致する名前の列すべての選択および列の値の置換

この例は、 id を含む名前のある employee_table のすべての列を選択し、 department_id 列の値の前に DEPT- を付加する方法を示しています。

SELECT * ILIKE '%id%' REPLACE('DEPT-' || department_id AS department_id) FROM employee_table;
Copy
+-------------+---------------+
| EMPLOYEE_ID | DEPARTMENT_ID |
|-------------+---------------|
|         101 | DEPT-1        |
|         102 | DEPT-2        |
|         103 | DEPT-2        |
+-------------+---------------+

複数テーブルからの全列選択、列の除外、および列の名前変更

この例では、2つのテーブルを結合し、 employee_table からの列1つを除いて、両方のテーブルからすべての列を選択します。この例では、 department_table から選択された列の1つの名前も変更します。

SELECT
  employee_table.* EXCLUDE department_id,
  department_table.* RENAME department_name AS department
FROM employee_table INNER JOIN department_table
  ON employee_table.department_id = department_table.department_id
ORDER BY department, last_name, first_name;
Copy
+-------------+------------+------------+---------------+------------------+
| EMPLOYEE_ID | LAST_NAME  | FIRST_NAME | DEPARTMENT_ID | DEPARTMENT       |
|-------------+------------+------------+---------------+------------------|
|         103 | Comstock   | Dana       |             2 | Customer Support |
|         102 | Levine     | Terry      |             2 | Customer Support |
|         101 | Montgomery | Pat        |             1 | Engineering      |
+-------------+------------+------------+---------------+------------------+

特定の列を選択する例(SELECT 列名)

名前による単一の列の選択

この例は、従業員の ID を知っている場合、従業員の姓を検索する方法を示しています。

SELECT last_name FROM employee_table WHERE employee_ID = 101;
+------------+
| LAST_NAME  |
|------------|
| Montgomery |
+------------+
Copy

結合されたテーブルからの名前による複数の列の選択

この例では、各従業員と各従業員が勤務する部門の名前をリストします。出力は部門名の順になり、各部門内では従業員は名前の順になります。このクエリは、結合を使用して、あるテーブルの情報を別のテーブルの情報に関連付けます。

SELECT department_name, last_name, first_name
    FROM employee_table INNER JOIN department_table
        ON employee_table.department_ID = department_table.department_ID
    ORDER BY department_name, last_name, first_name;
+------------------+------------+------------+
| DEPARTMENT_NAME  | LAST_NAME  | FIRST_NAME |
|------------------+------------+------------|
| Customer Support | Comstock   | Dana       |
| Customer Support | Levine     | Terry      |
| Engineering      | Montgomery | Pat        |
+------------------+------------+------------+
Copy

位置による列の選択

次の例は、 $ を使用して、列名ではなく列番号で列を指定する方法を示しています。

SELECT $2 FROM employee_table ORDER BY $2;
+------------+
| $2         |
|------------|
| Comstock   |
| Levine     |
| Montgomery |
+------------+
Copy

出力での列に対するエイリアスの指定

この例は、出力列を FROM 句のテーブルから直接取得する必要がないことを示しています。出力列は一般式にすることができます。この例では、半径が2.0である円の面積を計算します。この例では、出力に意味のある列名をつけるために列エイリアスを使用する方法も示しています。

SELECT pi() * 2.0 * 2.0 AS area_of_circle;
+----------------+
| AREA_OF_CIRCLE |
|----------------|
|   12.566370614 |
+----------------+
Copy

エラーケース: 別の列名に一致するエイリアスの指定

この例は、クエリで使用される他の列名と一致する列エイリアスを使用することが推奨されない理由を示しています。この GROUP BY クエリの結果は SQL コンパイラエラーであり、曖昧な列のエラーではありません。 table1product_id に割り当てられたエイリアス prod_id は、 table2prod_id 列の名前と一致します。このエラーに対する最も簡単な解決策は、列に別のエイリアスをつけることです。

CREATE OR REPLACE TABLE table1 (product_id NUMBER);

CREATE OR REPLACE TABLE table2 (prod_id NUMBER);

SELECT t1.product_id AS prod_id, t2.prod_id
  FROM table1 AS t1 JOIN table2 AS t2
    ON t1.product_id=t2.prod_id
  GROUP BY prod_id, t2.prod_id;
Copy
001104 (42601): SQL compilation error: error line 1 at position 7
'T1.PRODUCT_ID' in select clause is neither an aggregate nor in the group by clause.