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 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
)的查詢只會從基礎資料來源讀取一次,而具有 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)
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 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
都是集合運算。這些子句用於將多個選取陳述式的結果合併到單一結果集中
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
會將第一個查詢的結果集中的所有列與第二個查詢的結果集中的列合併。以下是一個最簡單的 UNION
子句範例。它選取值 13
,並將此結果集與選取值 42
的第二個查詢合併
SELECT 13
UNION
SELECT 42;
_col0
-------
13
42
(2 rows)
以下查詢示範 UNION
和 UNION ALL
之間的差異。它選取值 13
,並將此結果集與選取值 42
和 13
的第二個查詢合併
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
子句範例。它選取值 13
和 42
,並將此結果集與選取值 13
的第二個查詢合併。由於 42
僅存在於第一個查詢的結果集中,因此它不會包含在最終結果中。
SELECT * FROM (VALUES 13, 42)
INTERSECT
SELECT 13;
_col0
-------
13
(2 rows)
EXCEPT
EXCEPT
會傳回第一個查詢的結果集中有,但第二個查詢的結果集中沒有的列。以下是一個最簡單的 EXCEPT
子句範例。它選取值 13
和 42
,並將此結果集與選取值 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 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 子句會將輸出限制為只有五列 (由於查詢缺少 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¶
可以使用 UNNEST
將 ARRAY 或 MAP 展開為一個關係。陣列會被展開成單一欄位,而映射則會被展開成兩個欄位 (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_A
和 key_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)
注意
目前,只能從純量子查詢傳回單一欄位。