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 子句可能包含由輸入欄組成的任何表達式,或者它可以是透過位置選擇輸出欄的序數(從一開始)。

以下查詢是等效的。它們都使用輸出欄的序數位置的第一個查詢和使用輸入欄名稱的第二個查詢,將輸出依 nationkey 輸入欄分組

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 SETSCUBEROLLUP 語法的複雜聚合。這個語法允許使用者在單一查詢中,對多個欄集合執行需要聚合的分析。複雜分組運算不支援對由輸入欄組成的表達式進行分組。只允許欄名稱或序數。

複雜的分組運算通常等效於簡單的 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 SETSCUBEROLLUP)的查詢只會從基礎資料來源讀取一次,而具有 UNION ALL 的查詢會讀取基礎資料三次。這就是為什麼當資料來源不確定時,具有 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)

ALLDISTINCT 量詞決定重複的分組集合是否各自產生不同的輸出列。當在同一查詢中結合多個複雜的分組集合時,這特別有用。例如,以下查詢

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 SETSROLLUPCUBEGROUP BY 一起使用,且其引數必須與對應的 GROUPING SETSROLLUPCUBEGROUP 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_zipdestination_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 子句

UNIONINTERSECTEXCEPT 都是集合運算。這些子句用於將多個選取陳述式的結果合併到單一結果集中

query UNION [ALL | DISTINCT] query
query INTERSECT [DISTINCT] query
query EXCEPT [DISTINCT] query

引數 ALLDISTINCT 控制哪些列包含在最終結果集中。如果指定了引數 ALL,則會包含所有列,即使這些列相同。如果指定了引數 DISTINCT,則只會包含合併結果集中唯一的列。如果兩者都未指定,則預設行為為 DISTINCTALL 引數不支援 INTERSECTEXCEPT

除非透過括號明確指定順序,否則多個集合運算會從左到右處理。此外,INTERSECT 的繫結比 EXCEPTUNION 更緊密。這表示 A UNION B INTERSECT C EXCEPT DA UNION (B INTERSECT C) EXCEPT D 相同。

UNION

UNION 會將第一個查詢的結果集中的所有列與第二個查詢的結果集中的列合併。以下是一個最簡單的 UNION 子句範例。它選取值 13,並將此結果集與選取值 42 的第二個查詢合併

SELECT 13
UNION
SELECT 42;
 _col0
-------
    13
    42
(2 rows)

以下查詢示範 UNIONUNION ALL 之間的差異。它選取值 13,並將此結果集與選取值 4213 的第二個查詢合併

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 只會傳回第一個和第二個查詢的結果集中都有的列。以下是一個最簡單的 INTERSECT 子句範例。它選取值 1342,並將此結果集與選取值 13 的第二個查詢合併。由於 42 僅存在於第一個查詢的結果集中,因此它不會包含在最終結果中。

SELECT * FROM (VALUES 13, 42)
INTERSECT
SELECT 13;
 _col0
-------
    13
(2 rows)

EXCEPT

EXCEPT 會傳回第一個查詢的結果集中有,但第二個查詢的結果集中沒有的列。以下是一個最簡單的 EXCEPT 子句範例。它選取值 1342,並將此結果集與選取值 13 的第二個查詢合併。由於 13 也存在於第二個查詢的結果集中,因此它不會包含在最終結果中。

SELECT * FROM (VALUES 13, 42)
EXCEPT
SELECT 13;
 _col0
-------
   42
(2 rows)

ORDER BY 子句

ORDER BY 子句用於依據一個或多個輸出運算式排序結果集

ORDER BY expression [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...]

每個運算式都可能由輸出欄位組成,或者它可能是依位置選取輸出欄位的序數 (從一開始)。ORDER BY 子句會在任何 GROUP BYHAVING 子句之後,以及任何 OFFSETLIMITFETCH 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 子句會將輸出限制為只有五列 (由於查詢缺少 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 上的配置方式。此方法不保證獨立的取樣機率。

注意

這兩種方法都不允許對傳回的列數進行確定性的限制。

範例

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

可以使用 UNNESTARRAYMAP 展開為一個關係。陣列會被展開成單一欄位,而映射則會被展開成兩個欄位 (key, value)。UNNEST 也可以與多個參數一起使用,在這種情況下,它們會被展開成多個欄位,其列數與基數最高的參數相同(其他欄位會以 null 值填充)。UNNEST 可以選擇性地加上 WITH ORDINALITY 子句,在這種情況下,會在最後新增一個序數欄位。UNNEST 通常與 JOIN 一起使用,並且可以參考 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)

聯結 (Joins)

聯結允許您組合來自多個關係的資料。

交叉聯結 (CROSS JOIN)

交叉聯結會傳回兩個關係的笛卡爾積(所有組合)。交叉聯結可以使用明確的 CROSS JOIN 語法指定,也可以在 FROM 子句中指定多個關係。

以下兩個查詢是等效的

SELECT *
FROM nation
CROSS JOIN region;

SELECT *
FROM nation, region;

nation 表格包含 25 列,而 region 表格包含 5 列,因此這兩個表格之間的交叉聯結會產生 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)

限定欄位名稱

當聯結中的兩個關係具有相同名稱的欄位時,欄位參考必須使用關係別名(如果關係具有別名)或關係名稱來限定

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_Akey_B),後接 table_1 中的其餘欄位,然後是 table_2 中的其餘欄位。請注意,為了在查詢中參考聯結鍵,聯結鍵不包含在原始表格的欄位清單中。您無法使用表格前綴存取它們,並且如果您執行 SELECT table_1.*, table_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 值規則。子查詢必須正好產生一個欄位

SELECT name
FROM nation
WHERE regionkey IN (SELECT regionkey FROM region)

純量子查詢

純量子查詢是一個非相關的子查詢,它傳回零列或一列。如果子查詢產生超過一列,則會發生錯誤。如果子查詢沒有產生任何列,則傳回的值為 NULL

SELECT name
FROM nation
WHERE regionkey = (SELECT max(regionkey) FROM region)

注意

目前,只能從純量子查詢傳回單一欄位。