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>, ... )
}
]
SELECT * の後に以下のキーワードの組み合わせを指定できます。キーワードは以下の順番にする必要があります。
SELECT * ILIKE ... REPLACE ...
SELECT * ILIKE ... RENAME ...
SELECT * ILIKE ... REPLACE ... RENAME ...
SELECT * EXCLUDE ... REPLACE ...
SELECT * EXCLUDE ... RENAME ...
SELECT * EXCLUDE ... REPLACE ... RENAME ...
SELECT * REPLACE ... RENAME ...
特定の列の選択¶
[ ... ]
SELECT [ { ALL | DISTINCT } ]
[ TOP <n> ]
{
[{<object_name>|<alias>}.]<col_name>
| [{<object_name>|<alias>}.]$<col_position>
| <expr>
}
[ [ AS ] <col_alias> ]
[ , ... ]
[ ... ]
ステートメントとしての SELECT およびステートメント内の他の句の詳細については、 クエリ構文 をご参照ください。
パラメーター¶
ALL | DISTINCT
結果セットで重複排除を実行するかどうかを指定します。
ALL
には、結果セットのすべての値が含まれます。DISTINCT
は、結果セットから重複した値を削除します。
デフォルト:
ALL
TOP n
返される結果の最大数を指定します。 TOP <n> をご参照ください。
object_name
または .alias
FROM 句で定義されているオブジェクト識別子またはオブジェクトエイリアスを指定します。
*
アスタリスクは、指定されたオブジェクトのすべての列、または
*
がオブジェクト名またはエイリアスで修飾されていない場合、すべてのオブジェクトのすべての列を出力に含めることを示す略記です。*
を指定する場合、ILIKE
、EXCLUDE
、REPLACE
、および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 ...
REPLACE (expr AS col_name [ , expr AS col_name, ...] )
col_name
の値を評価式expr
の値で置き換えます。たとえば、文字列
'DEPT-'
をdepartment_id
列にある各値に追加するには、SELECT REPLACE ('DEPT-' || department_id AS department_id) ...
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 ...
注釈
SELECT *
の後にキーワードの組み合わせを指定する場合は、ILIKE
とEXCLUDE
の両方を指定することはできません。RENAME
またはREPLACE
でEXCLUDE
を指定した場合は、RENAME
またはREPLACE
の前にEXCLUDE
を指定する必要があります。SELECT * EXCLUDE col_a RENAME col_b AS alias_b ...
SELECT * EXCLUDE employee_id REPLACE ('DEPT-' || department_id AS department_id) ...
EXCLUDE
とRENAME
で同じ列を指定することはできません。
RENAME
またはREPLACE
でILIKE
を指定する場合は、最初にILIKE
を指定する必要があります。SELECT * ILIKE '%id%' RENAME department_id AS department ...
SELECT * ILIKE '%id%' REPLACE ('DEPT-' || department_id AS department_id) ...
REPLACE
とRENAME
を指定した場合は、最初に
REPLACE
を指定する必要があります。SELECT * REPLACE ('DEPT-' || department_id AS department_id) RENAME employee_id as employee ...
REPLACE
とRENAME
で同じ列名を指定できます。SELECT * REPLACE ('DEPT-' || department_id AS department_id) RENAME department_id as department ...
col_name
FROM 句で定義されている列識別子を指定します。
$col_position
FROM 句で定義されている列の位置(1ベース)を指定します。列がテーブルから参照される場合、この数はテーブル内の列の最大数を超えることはできません。
expr
特定の行の特定の値に評価される数式などの式を指定します。
[ AS ] col_alias
結果の式に割り当てられる列エイリアスを指定します。これは、最上位の SELECT リストでの表示名、およびインラインビューでの列名として使用されます。
クエリで参照される他の列の名前と同じ列エイリアスを割り当てないでください。例えば、
prod_id
とproduct_id
という名前の列を選択している場合、prod_id
をproduct_id
というエイリアスにしないでください。 エラーケース: 別の列名に一致するエイリアスの指定 をご参照ください。
FORUPDATE 句の使用¶
オプションの FOR UPDATE 句を使用して、将来の更新のために結果をロックします。
SELECT ...
FROM ...
[ ... ]
FOR UPDATE [ NOWAIT | WAIT <wait_time> ]
パラメーター¶
WAIT
このステートメントがロックを取得するまでの最大待機時間(秒)を整数で指定します。
使用上の注意¶
FOR UPDATE
は、SELECT
ステートメントの最後の句にする必要があります。FOR UPDATE
は、 サブクエリ では使用できません。NOWAIT
またはWAIT
が指定されていない場合は、NOWAIT
がデフォルトのオプションです。FOR UPDATE
句は、以下の機能とは互換性がありません。複数のテーブルの使用。
注釈
ハイブリッドテーブルは READ COMMITTED
分離レベルをサポートするため、 FOR UPDATE
句は読み取りの安定性を保証できません。
列
ID
のみを持つテーブルT
は2つのタプル、5と10で始まります。トランザクション
T1
のSELECT * FROM T WHERE ID < 20 FOR UPDATE
は2つのタプル、5と10を返し、それらをロックします。別のトランザクション
T2
からのDELETE FROM T WHERE ID = 5
は、T1
が完了(コミットまたはロールバック)するまで待機する必要があります。
しかし、別のトランザクション
T3
のINSERT 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 );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');
すべての列を選択する例(SELECT *)¶
テーブル内にあるすべての列の選択¶
この例は、 employee_table
内にあるすべての列を選択する方法を示しています。
SELECT * FROM employee_table;
+-------------+------------+------------+---------------+
| 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;
+-------------+---------------+
| EMPLOYEE_ID | DEPARTMENT_ID |
|-------------+---------------|
| 101 | 1 |
| 102 | 2 |
| 103 | 2 |
+-------------+---------------+
1つの列を除くすべての列の選択¶
この例は、 department_id
列を除く employee_table
のすべての列を選択する方法を示しています。
SELECT * EXCLUDE department_id FROM employee_table;
+-------------+------------+------------+
| 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;
+------------+------------+
| LAST_NAME | FIRST_NAME |
|------------+------------|
| Montgomery | Pat |
| Levine | Terry |
| Comstock | Dana |
+------------+------------+
すべての列の選択と1つの列の名前変更¶
次の例は、 employee_table
のすべての列を選択し、 department_id
列の名前を変更する方法を示しています。
SELECT * RENAME department_id AS department FROM employee_table;
+-------------+------------+------------+------------+
| 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;
+-----+------------+------------+------------+
| 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;
+-----+------------+------------+
| 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;
+-------------+------------+
| 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;
+-------------+------------+------------+---------------+
| 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;
+-------------+------------+------------+------------+
| 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;
+-------------+---------------+
| 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;
+-------------+------------+------------+---------------+------------------+
| 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 | +------------+
結合されたテーブルからの名前による複数の列の選択¶
この例では、各従業員と各従業員が勤務する部門の名前をリストします。出力は部門名の順になり、各部門内では従業員は名前の順になります。このクエリは、結合を使用して、あるテーブルの情報を別のテーブルの情報に関連付けます。
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 | +------------------+------------+------------+
位置による列の選択¶
次の例は、 $
を使用して、列名ではなく列番号で列を指定する方法を示しています。
SELECT $2 FROM employee_table ORDER BY $2; +------------+ | $2 | |------------| | Comstock | | Levine | | Montgomery | +------------+
出力での列に対するエイリアスの指定¶
この例は、出力列を FROM
句のテーブルから直接取得する必要がないことを示しています。出力列は一般式にすることができます。この例では、半径が2.0である円の面積を計算します。この例では、出力に意味のある列名をつけるために列エイリアスを使用する方法も示しています。
SELECT pi() * 2.0 * 2.0 AS area_of_circle; +----------------+ | AREA_OF_CIRCLE | |----------------| | 12.566370614 | +----------------+
エラーケース: 別の列名に一致するエイリアスの指定¶
この例は、クエリで使用される他の列名と一致する列エイリアスを使用することが推奨されない理由を示しています。この GROUP BY クエリの結果は SQL コンパイラエラーであり、曖昧な列のエラーではありません。 table1
の product_id
に割り当てられたエイリアス prod_id
は、 table2
の prod_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;
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.