SELECT¶
構文¶
[ WITH with_query [, ...] ]
SELECT [ ALL | DISTINCT ] select_expr [, ...]
[ FROM from_item [, ...] ]
[ WHERE condition ]
[ GROUP BY [ ALL | DISTINCT ] grouping_element [, ...] ]
[ HAVING condition]
[ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ]
[ ORDER BY expression [ ASC | DESC ] [, ...] ]
[ OFFSET count [ { ROW | ROWS } ] ]
[ { LIMIT [ count | ALL ] } ]
ここで、from_item
は以下のいずれかです。
table_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
from_item join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ]
そして、join_type
は以下のいずれかです。
[ INNER ] JOIN
LEFT [ OUTER ] JOIN
RIGHT [ OUTER ] JOIN
FULL [ OUTER ] JOIN
CROSS JOIN
そして、grouping_element
は以下のいずれかです。
()
expression
GROUPING SETS ( ( column [, ...] ) [, ...] )
CUBE ( column [, ...] )
ROLLUP ( column [, ...] )
説明¶
ゼロ個以上のテーブルから行を取得します。
WITH 句¶
WITH
句は、クエリ内で使用するための名前付き関係を定義します。ネストされたクエリをフラット化したり、サブクエリを簡略化したりすることができます。たとえば、以下のクエリは同等です。
SELECT a, b
FROM (
SELECT a, MAX(b) AS b FROM t GROUP BY a
) AS x;
WITH x AS (SELECT a, MAX(b) AS b FROM t GROUP BY a)
SELECT a, b FROM x;
これは複数のサブクエリでも機能します。
WITH
t1 AS (SELECT a, MAX(b) AS b FROM x GROUP BY a),
t2 AS (SELECT a, AVG(d) AS d FROM y GROUP BY a)
SELECT t1.*, t2.*
FROM t1
JOIN t2 ON t1.a = t2.a;
さらに、WITH
句内の関係はチェーンすることができます。
WITH
x AS (SELECT a FROM t),
y AS (SELECT a AS b FROM x),
z AS (SELECT b AS c FROM y)
SELECT c FROM z;
警告
現在、WITH
句の SQL は、名前付き関係が使用される場所であればどこでもインライン化されます。つまり、関係が複数回使用され、クエリが非決定論的である場合、結果が毎回異なる可能性があります。
GROUP BY 句¶
GROUP BY
句は、SELECT
ステートメントの出力を、一致する値を含む行のグループに分割します。単純な GROUP BY
句には、入力列で構成される任意の式を含めることができます。または、出力列を位置(1 から始まる)で選択する序数にすることもできます。
以下のクエリは同等です。どちらも nationkey
入力列で出力をグループ化しており、最初のクエリは出力列の序数位置を使用し、2 番目のクエリは入力列名を使用しています。
SELECT count(*), nationkey FROM customer GROUP BY 2;
SELECT count(*), nationkey FROM customer GROUP BY nationkey;
GROUP BY
句は、select ステートメントの出力に表示されない入力列名で出力をグループ化できます。たとえば、次のクエリは、入力列 mktsegment
を使用して customer
テーブルの行数を生成します。
SELECT count(*) FROM customer GROUP BY mktsegment;
_col0
-------
29968
30142
30189
29949
29752
(5 rows)
SELECT
ステートメントで GROUP BY
句が使用される場合、すべての出力式は集計関数または GROUP BY
句に存在する列である必要があります。
複雑なグループ化操作
Presto は、GROUPING SETS
、CUBE
、ROLLUP
構文を使用した複雑な集計もサポートしています。この構文により、ユーザーは単一のクエリで複数の列セットの集計を必要とする分析を実行できます。複雑なグループ化操作では、入力列で構成される式のグループ化はサポートされていません。列名または序数のみが許可されます。
複雑なグループ化操作は、多くの場合、以下の例に示すように、単純な GROUP BY
式の UNION ALL
と同等です。ただし、集計のデータソースが非決定論的である場合、この等価性は適用されません.
GROUPING SETS
グループ化セットにより、ユーザーはグループ化する列の複数のリストを指定できます。グループ化列の特定のサブリストに含まれていない列は、NULL
に設定されます。
SELECT * FROM shipping;
origin_state | origin_zip | destination_state | destination_zip | package_weight
--------------+------------+-------------------+-----------------+----------------
California | 94131 | New Jersey | 8648 | 13
California | 94131 | New Jersey | 8540 | 42
New Jersey | 7081 | Connecticut | 6708 | 225
California | 90210 | Connecticut | 6927 | 1337
California | 94131 | Colorado | 80302 | 5
New York | 10002 | New Jersey | 8540 | 3
(6 rows)
GROUPING SETS
のセマンティクスは、このクエリの例で示されています。
SELECT origin_state, origin_zip, destination_state, sum(package_weight)
FROM shipping
GROUP BY GROUPING SETS (
(origin_state),
(origin_state, origin_zip),
(destination_state));
origin_state | origin_zip | destination_state | _col0
--------------+------------+-------------------+-------
New Jersey | NULL | NULL | 225
California | NULL | NULL | 1397
New York | NULL | NULL | 3
California | 90210 | NULL | 1337
California | 94131 | NULL | 60
New Jersey | 7081 | NULL | 225
New York | 10002 | NULL | 3
NULL | NULL | Colorado | 5
NULL | NULL | New Jersey | 58
NULL | NULL | Connecticut | 1562
(10 rows)
上記のクエリは、論理的には複数の GROUP BY
クエリの UNION ALL
と同等と見なすことができます。
SELECT origin_state, NULL, NULL, sum(package_weight)
FROM shipping GROUP BY origin_state
UNION ALL
SELECT origin_state, origin_zip, NULL, sum(package_weight)
FROM shipping GROUP BY origin_state, origin_zip
UNION ALL
SELECT NULL, NULL, destination_state, sum(package_weight)
FROM shipping GROUP BY destination_state;
ただし、複雑なグループ化構文(GROUPING SETS
、CUBE
、または ROLLUP
)を使用したクエリは、基になるデータソースを 1 回だけ読み取りますが、UNION ALL
を使用したクエリは基になるデータを 3 回読み取ります。そのため、データソースが決定論的でない場合、UNION ALL
を使用したクエリは一貫性のない結果を生成する可能性があります。
CUBE
CUBE
演算子は、特定の列セットに対して可能なすべてのグループ化セット(つまり、べき集合)を生成します。たとえば、クエリ
SELECT origin_state, destination_state, sum(package_weight)
FROM shipping
GROUP BY CUBE (origin_state, destination_state);
は以下と同等です。
SELECT origin_state, destination_state, sum(package_weight)
FROM shipping
GROUP BY GROUPING SETS (
(origin_state, destination_state),
(origin_state),
(destination_state),
());
origin_state | destination_state | _col0
--------------+-------------------+-------
California | New Jersey | 55
California | Colorado | 5
New York | New Jersey | 3
New Jersey | Connecticut | 225
California | Connecticut | 1337
California | NULL | 1397
New York | NULL | 3
New Jersey | NULL | 225
NULL | New Jersey | 58
NULL | Connecticut | 1562
NULL | Colorado | 5
NULL | NULL | 1625
(12 rows)
ROLLUP
ROLLUP
演算子は、特定の列セットに対して可能なすべての小計を生成します。たとえば、クエリ
SELECT origin_state, origin_zip, sum(package_weight)
FROM shipping
GROUP BY ROLLUP (origin_state, origin_zip);
origin_state | origin_zip | _col2
--------------+------------+-------
California | 94131 | 60
California | 90210 | 1337
New Jersey | 7081 | 225
New York | 10002 | 3
California | NULL | 1397
New York | NULL | 3
New Jersey | NULL | 225
NULL | NULL | 1625
(8 rows)
は以下と同等です。
SELECT origin_state, origin_zip, sum(package_weight)
FROM shipping
GROUP BY GROUPING SETS ((origin_state, origin_zip), (origin_state), ());
複数のグループ化式の組み合わせ
同じクエリ内の複数のグループ化式は、クロス積のセマンティクスを持つものとして解釈されます。たとえば、次のクエリ
SELECT origin_state, destination_state, origin_zip, sum(package_weight)
FROM shipping
GROUP BY
GROUPING SETS ((origin_state, destination_state)),
ROLLUP (origin_zip);
は次のように書き直すことができます。
SELECT origin_state, destination_state, origin_zip, sum(package_weight)
FROM shipping
GROUP BY
GROUPING SETS ((origin_state, destination_state)),
GROUPING SETS ((origin_zip), ());
は論理的には以下と同等です。
SELECT origin_state, destination_state, origin_zip, sum(package_weight)
FROM shipping
GROUP BY GROUPING SETS (
(origin_state, destination_state, origin_zip),
(origin_state, destination_state));
origin_state | destination_state | origin_zip | _col3
--------------+-------------------+------------+-------
New York | New Jersey | 10002 | 3
California | New Jersey | 94131 | 55
New Jersey | Connecticut | 7081 | 225
California | Connecticut | 90210 | 1337
California | Colorado | 94131 | 5
New York | New Jersey | NULL | 3
New Jersey | Connecticut | NULL | 225
California | Colorado | NULL | 5
California | Connecticut | NULL | 1337
California | New Jersey | NULL | 55
(10 rows)
ALL
および DISTINCT
量指定子は、重複するグループ化セットがそれぞれ個別の出力行を生成するかどうかを決定します。これは、同じクエリで複数の複雑なグループ化セットが組み合わされる場合に特に役立ちます。たとえば、次のクエリ
SELECT origin_state, destination_state, origin_zip, sum(package_weight)
FROM shipping
GROUP BY ALL
CUBE (origin_state, destination_state),
ROLLUP (origin_state, origin_zip);
は以下と同等です。
SELECT origin_state, destination_state, origin_zip, sum(package_weight)
FROM shipping
GROUP BY GROUPING SETS (
(origin_state, destination_state, origin_zip),
(origin_state, origin_zip),
(origin_state, destination_state, origin_zip),
(origin_state, origin_zip),
(origin_state, destination_state),
(origin_state),
(origin_state, destination_state),
(origin_state),
(origin_state, destination_state),
(origin_state),
(destination_state),
());
ただし、クエリが GROUP BY
に DISTINCT
量指定子を使用する場合
SELECT origin_state, destination_state, origin_zip, sum(package_weight)
FROM shipping
GROUP BY DISTINCT
CUBE (origin_state, destination_state),
ROLLUP (origin_state, origin_zip);
一意のグループ化セットのみが生成されます。
SELECT origin_state, destination_state, origin_zip, sum(package_weight)
FROM shipping
GROUP BY GROUPING SETS (
(origin_state, destination_state, origin_zip),
(origin_state, origin_zip),
(origin_state, destination_state),
(origin_state),
(destination_state),
());
デフォルトのセット量指定子は ALL
です。
GROUPING 操作
grouping(col1, ..., colN) -> bigint
grouping 操作は、10 進数に変換されたビットセットを返し、グループ化にどの列が存在するかを示します。GROUPING SETS
、ROLLUP
、CUBE
、または GROUP BY
と組み合わせて使用する必要があり、その引数は対応する GROUPING SETS
、ROLLUP
、CUBE
、または GROUP BY
句で参照される列と正確に一致する必要があります。
特定の行の結果のビットセットを計算するために、ビットは引数列に割り当てられ、最右端の列が最下位ビットになります。特定のグループ化の場合、対応する列がグループ化に含まれている場合はビットは 0 に設定され、そうでない場合は 1 に設定されます。たとえば、以下のクエリを考えてみましょう。
SELECT origin_state, origin_zip, destination_state, sum(package_weight),
grouping(origin_state, origin_zip, destination_state)
FROM shipping
GROUP BY GROUPING SETS (
(origin_state),
(origin_state, origin_zip),
(destination_state));
origin_state | origin_zip | destination_state | _col3 | _col4
--------------+------------+-------------------+-------+-------
California | NULL | NULL | 1397 | 3
New Jersey | NULL | NULL | 225 | 3
New York | NULL | NULL | 3 | 3
California | 94131 | NULL | 60 | 1
New Jersey | 7081 | NULL | 225 | 1
California | 90210 | NULL | 1337 | 1
New York | 10002 | NULL | 3 | 1
NULL | NULL | New Jersey | 58 | 6
NULL | NULL | Connecticut | 1562 | 6
NULL | NULL | Colorado | 5 | 6
(10 rows)
上記の最初のグループ化には、origin_state
列のみが含まれ、origin_zip
列と destination_state
列は除外されます。そのグループ化のために構築されたビットセットは 011
であり、最上位ビットは origin_state
を表します。
HAVING 句¶
HAVING
句は、集約関数およびGROUP BY
句と組み合わせて使用され、選択されるグループを制御します。 HAVING
句は、指定された条件を満たさないグループを除外します。 HAVING
は、グループと集計が計算された後にグループをフィルタリングします。
次の例では、customer
テーブルに対してクエリを実行し、指定された値よりも口座残高が大きいグループを選択します。
SELECT count(*), mktsegment, nationkey,
CAST(sum(acctbal) AS bigint) AS totalbal
FROM customer
GROUP BY mktsegment, nationkey
HAVING sum(acctbal) > 5700000
ORDER BY totalbal DESC;
_col0 | mktsegment | nationkey | totalbal
-------+------------+-----------+----------
1272 | AUTOMOBILE | 19 | 5856939
1253 | FURNITURE | 14 | 5794887
1248 | FURNITURE | 9 | 5784628
1243 | FURNITURE | 12 | 5757371
1231 | HOUSEHOLD | 3 | 5753216
1251 | MACHINERY | 2 | 5719140
1247 | FURNITURE | 8 | 5701952
(7 rows)
UNION | INTERSECT | EXCEPT 句¶
UNION
、INTERSECT
、およびEXCEPT
はすべて集合演算です。これらの句は、複数のSELECTステートメントの結果を単一の結果セットに結合するために使用されます。
query UNION [ALL | DISTINCT] query
query INTERSECT [DISTINCT] query
query EXCEPT [DISTINCT] query
引数ALL
またはDISTINCT
は、最終結果セットにどの行が含まれるかを制御します。引数ALL
が指定されている場合、行が同一であってもすべての行が含まれます。引数DISTINCT
が指定されている場合、一意の行のみが結合された結果セットに含まれます。どちらも指定されていない場合、動作はデフォルトでDISTINCT
になります。 ALL
引数は、INTERSECT
またはEXCEPT
ではサポートされていません。
複数の集合演算は、括弧によって順序が明示的に指定されていない限り、左から右に処理されます。さらに、INTERSECT
はEXCEPT
およびUNION
よりも強く結合します。つまり、A UNION B INTERSECT C EXCEPT D
はA UNION (B INTERSECT C) EXCEPT D
と同じです。
UNION
UNION
は、最初のクエリの結果セットにあるすべての行と、2番目のクエリの結果セットにある行を結合します。以下は、最も単純なUNION
句の例の1つです。値13
を選択し、この結果セットを値42
を選択する2番目のクエリと結合します。
SELECT 13
UNION
SELECT 42;
_col0
-------
13
42
(2 rows)
次のクエリは、UNION
とUNION ALL
の違いを示しています。値13
を選択し、この結果セットを値42
と13
を選択する2番目のクエリと結合します。
SELECT 13
UNION
SELECT * FROM (VALUES 42, 13);
_col0
-------
13
42
(2 rows)
SELECT 13
UNION ALL
SELECT * FROM (VALUES 42, 13);
_col0
-------
13
42
13
(2 rows)
INTERSECT
INTERSECT
は、最初と2番目のクエリの両方の結果セットにある行のみを返します。以下は、最も単純なINTERSECT
句の例の1つです。値13
と42
を選択し、この結果セットを値13
を選択する2番目のクエリと結合します。 42
は最初のクエリの結果セットにのみ存在するため、最終結果には含まれません。
SELECT * FROM (VALUES 13, 42)
INTERSECT
SELECT 13;
_col0
-------
13
(2 rows)
EXCEPT
EXCEPT
は、最初のクエリの結果セットにはあるが、2番目のクエリの結果セットにはない行を返します。以下は、最も単純なEXCEPT
句の例の1つです。値13
と42
を選択し、この結果セットを値13
を選択する2番目のクエリと結合します。 13
は2番目のクエリの結果セットにも存在するため、最終結果には含まれません。
SELECT * FROM (VALUES 13, 42)
EXCEPT
SELECT 13;
_col0
-------
42
(2 rows)
ORDER BY 句¶
ORDER BY
句は、結果セットを1つ以上の出力式でソートするために使用されます。
ORDER BY expression [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...]
各式は出力列で構成されている場合もあれば、1から始まる位置で出力列を選択する序数である場合もあります。 ORDER BY
句は、GROUP BY
句またはHAVING
句の後、OFFSET
、LIMIT
、またはFETCH FIRST
句の前に評価されます。デフォルトのNULL順序は、順序方向に関係なく、NULLS LAST
です。
OFFSET 句¶
OFFSET
句は、結果セットから先頭の行を指定された数だけ破棄するために使用されます。
OFFSET count [ ROW | ROWS ]
ORDER BY
句が存在する場合、OFFSET
句はソートされた結果セットに対して評価され、先頭の行が破棄された後もセットはソートされたままになります。
SELECT name FROM nation ORDER BY name OFFSET 22;
name
----------------
UNITED KINGDOM
UNITED STATES
VIETNAM
(3 rows)
それ以外の場合、どの行が破棄されるかは任意です。 OFFSET
句で指定されたカウントが結果セットのサイズ以上の場合、最終結果は空になります。
LIMIT 句¶
LIMIT
句は、結果セットの行数を制限します。 LIMIT ALL
は、LIMIT
句を省略するのと同じです。
LIMIT { count | ALL }
次の例では、大きなテーブルに対してクエリを実行しますが、LIMIT句により、出力は5行のみに制限されます(クエリにORDER BY
がないため、どの行が返されるかは任意です)。
SELECT orderdate FROM orders LIMIT 5;
o_orderdate
-------------
1996-04-14
1992-01-15
1995-02-01
1995-11-12
1992-04-26
(5 rows)
LIMIT ALL
は、LIMIT
句を省略するのと同じです。
OFFSET
句が存在する場合、LIMIT
句はOFFSET
句の後に評価されます。
SELECT * FROM (VALUES 5, 2, 4, 1, 3) t(x) ORDER BY x OFFSET 2 LIMIT 2;
x
---
3
4
(2 rows)
TABLESAMPLE¶
複数のサンプリング方法があります。
BERNOULLI
各行は、サンプルの割合の確率でテーブルサンプルに選択されます。 Bernoulliメソッドを使用してテーブルをサンプリングする場合、テーブルのすべての物理ブロックがスキャンされ、特定の行がスキップされます(サンプルの割合と実行時に計算されたランダム値の比較に基づく)。
行が結果に含まれる確率は、他の行とは無関係です。これは、サンプリングされたテーブルをディスクから読み取るために必要な時間を短縮しません。サンプリングされた出力がさらに処理される場合、クエリ全体の時間に影響を与える可能性があります。
SYSTEM
このサンプリング方法は、テーブルを論理的なデータセグメントに分割し、この粒度でテーブルをサンプリングします。このサンプリング方法は、特定のデータセグメントからすべての行を選択するか、スキップします(サンプルの割合と実行時に計算されたランダム値の比較に基づく)。
システムサンプリングで選択される行は、どのコネクタが使用されるかによって異なります。たとえば、Hiveで使用する場合、データがHDFSにどのように配置されているかによって異なります。この方法は、独立したサンプリング確率を保証しません。
注記
2つの方法のどちらも、返される行数の確定的な境界を許可しません。
例
SELECT *
FROM users TABLESAMPLE BERNOULLI (50);
SELECT *
FROM users TABLESAMPLE SYSTEM (75);
結合でのサンプリングの使用
SELECT o.*, i.*
FROM orders o TABLESAMPLE SYSTEM (10)
JOIN lineitem i TABLESAMPLE BERNOULLI (40)
ON o.orderkey = i.orderkey;
UNNEST¶
UNNEST
は、ARRAYまたはMAPをリレーションに展開するために使用できます。配列は単一の列に展開され、マップは2つの列(キー、値)に展開されます。 UNNEST
は複数の引数で使用することもでき、その場合、それらは複数の列に展開され、カーディナリティが最も高い引数と同じ数の行になります(他の列はNULLで埋められます)。 UNNEST
にはオプションでWITH ORDINALITY
句を含めることができ、その場合、追加の序数列が最後に追加されます。 UNNEST
は通常JOIN
で使用され、結合の左側のリレーションの列を参照できます。
単一の配列列の使用
SELECT student, score
FROM tests
CROSS JOIN UNNEST(scores) AS t (score);
複数の配列列の使用
SELECT numbers, animals, n, a
FROM (
VALUES
(ARRAY[2, 5], ARRAY['dog', 'cat', 'bird']),
(ARRAY[7, 8, 9], ARRAY['cow', 'pig'])
) AS x (numbers, animals)
CROSS JOIN UNNEST(numbers, animals) AS t (n, a);
numbers | animals | n | a
-----------+------------------+------+------
[2, 5] | [dog, cat, bird] | 2 | dog
[2, 5] | [dog, cat, bird] | 5 | cat
[2, 5] | [dog, cat, bird] | NULL | bird
[7, 8, 9] | [cow, pig] | 7 | cow
[7, 8, 9] | [cow, pig] | 8 | pig
[7, 8, 9] | [cow, pig] | 9 | NULL
(6 rows)
WITH ORDINALITY
句
SELECT numbers, n, a
FROM (
VALUES
(ARRAY[2, 5]),
(ARRAY[7, 8, 9])
) AS x (numbers)
CROSS JOIN UNNEST(numbers) WITH ORDINALITY AS t (n, a);
numbers | n | a
-----------+---+---
[2, 5] | 2 | 1
[2, 5] | 5 | 2
[7, 8, 9] | 7 | 1
[7, 8, 9] | 8 | 2
[7, 8, 9] | 9 | 3
(5 rows)
単一のマップ列の使用
SELECT
animals, a, n
FROM (
VALUES
(MAP(ARRAY['dog', 'cat', 'bird'], ARRAY[1, 2, 0])),
(MAP(ARRAY['dog', 'cat'], ARRAY[4, 5]))
) AS x (animals)
CROSS JOIN UNNEST(animals) AS t (a, n);
animals | a | n
----------------------------+------+---
{"cat":2,"bird":0,"dog":1} | dog | 1
{"cat":2,"bird":0,"dog":1} | cat | 2
{"cat":2,"bird":0,"dog":1} | bird | 0
{"cat":5,"dog":4} | dog | 4
{"cat":5,"dog":4} | cat | 5
(5 rows)
結合¶
結合を使用すると、複数のリレーションからのデータを結合できます。
CROSS JOIN¶
クロス結合は、2つのリレーションのデカルト積(すべての組み合わせ)を返します。クロス結合は、明示的なCROSS JOIN
構文を使用するか、FROM
句で複数のリレーションを指定することによって指定できます。
次の両方のクエリは同等です。
SELECT *
FROM nation
CROSS JOIN region;
SELECT *
FROM nation, region;
nation
テーブルには25行、region
テーブルには5行が含まれているため、2つのテーブルのクロス結合は125行を生成します。
SELECT n.name AS nation, r.name AS region
FROM nation AS n
CROSS JOIN region AS r
ORDER BY 1, 2;
nation | region
----------------+-------------
ALGERIA | AFRICA
ALGERIA | AMERICA
ALGERIA | ASIA
ALGERIA | EUROPE
ALGERIA | MIDDLE EAST
ARGENTINA | AFRICA
ARGENTINA | AMERICA
...
(125 rows)
列名の修飾¶
結合における2つのリレーションに同じ名前の列がある場合、列参照は、リレーションのエイリアス(リレーションにエイリアスがある場合)またはリレーション名を使用して修飾する必要があります。
SELECT nation.name, region.name
FROM nation
CROSS JOIN region;
SELECT n.name, r.name
FROM nation AS n
CROSS JOIN region AS r;
SELECT n.name, r.name
FROM nation n
CROSS JOIN region r;
以下のクエリは、Column 'name' is ambiguous
というエラーで失敗します。
SELECT name
FROM nation
CROSS JOIN region;
USING句¶
USING
句を使用すると、結合する両方のテーブルに結合キーと同じ名前がある場合、より短いクエリを作成できます。
例えば
SELECT *
FROM table_1
JOIN table_2
ON table_1.key_A = table_2.key_A AND table_1.key_B = table_2.key_B
は以下のように書き直すことができます。
SELECT *
FROM table_1
JOIN table_2
USING (key_A, key_B)
USING
を使用した JOIN
の出力は、結合キー列(上記の例では key_A
と key_B
)のコピー1つと、それに続いて table_1
の残りの列、そして table_2
の残りの列となります。結合キーは、クエリ内でそれらを参照する目的で、元のテーブルの列リストには含まれないことに注意してください。テーブルプレフィックスを使用してアクセスすることはできず、SELECT table_1.*, table_2.*
を実行した場合、結合列は出力に含まれません。
以下の2つのクエリは同等です。
SELECT *
FROM (
VALUES
(1, 3, 10),
(2, 4, 20)
) AS table_1 (key_A, key_B, y1)
LEFT JOIN (
VALUES
(1, 3, 100),
(2, 4, 200)
) AS table_2 (key_A, key_B, y2)
USING (key_A, key_B)
-----------------------------
SELECT key_A, key_B, table_1.*, table_2.*
FROM (
VALUES
(1, 3, 10),
(2, 4, 20)
) AS table_1 (key_A, key_B, y1)
LEFT JOIN (
VALUES
(1, 3, 100),
(2, 4, 200)
) AS table_2 (key_A, key_B, y2)
USING (key_A, key_B)
そして、以下の出力を生成します。
key_A | key_B | y1 | y2
-------+-------+----+-----
1 | 3 | 10 | 100
2 | 4 | 20 | 200
(2 rows)
サブクエリ¶
サブクエリは、クエリで構成される式です。サブクエリは、サブクエリ外の列を参照する場合、相関サブクエリとなります。論理的には、サブクエリは、周囲のクエリの各行に対して評価されます。したがって、参照される列は、サブクエリの単一の評価中は定数になります。
注記
相関サブクエリのサポートは限定的です。すべての標準形式がサポートされているわけではありません。
EXISTS述語¶
EXISTS
述語は、サブクエリが行を返すかどうかを判断します。
SELECT name
FROM nation
WHERE EXISTS (SELECT * FROM region WHERE region.regionkey = nation.regionkey)
IN述語¶
IN
述語は、サブクエリによって生成された値が指定された式と等しいかどうかを判断します。IN
の結果は、NULLに関する標準ルールに従います。サブクエリは、正確に1つの列を生成する必要があります。
SELECT name
FROM nation
WHERE regionkey IN (SELECT regionkey FROM region)
スカラサブクエリ¶
スカラサブクエリは、0行または1行を返す非相関サブクエリです。サブクエリが複数の行を生成するのはエラーです。サブクエリが行を生成しない場合、戻り値は NULL
です。
SELECT name
FROM nation
WHERE regionkey = (SELECT max(regionkey) FROM region)
注記
現在、スカラサブクエリからは単一の列のみを返すことができます。