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
输入列对输出进行分组,第一个查询使用输出列的序数位置,第二个查询使用输入列名
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)
当 GROUP BY
子句用于 SELECT
语句中时,所有输出表达式必须是聚合函数或存在于 GROUP BY
子句中的列。
复杂分组操作
Presto 还支持使用 GROUPING SETS
、CUBE
和 ROLLUP
语法的复杂聚合。此语法允许用户执行需要在单个查询中对多个列集进行聚合的分析。复杂分组操作不支持对由输入列组成的表达式进行分组。只允许使用列名或序数。
复杂分组操作通常等效于 UNION ALL
的简单 GROUP BY
表达式,如以下示例所示。但是,当聚合的数据源是非确定性的时,这种等效性不适用。
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
都是集合运算。这些子句用于将多个 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
将第一个查询结果集中的所有行与第二个查询结果集中的所有行组合在一起。以下是最简单的 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 } ] [, ...]
每个表达式可以由输出列组成,也可以是按位置选择输出列的序数(从 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 子句将输出限制为只有五行(因为查询缺少 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
可用于将 数组 或 映射 展开为关系。数组展开为一列,映射展开为两列(键,值)。 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¶
交叉连接返回两个关系的笛卡尔积(所有组合)。 交叉连接可以使用显式 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
的结果遵循空值的标准规则。 子查询必须产生正好一列
SELECT name
FROM nation
WHERE regionkey IN (SELECT regionkey FROM region)
标量子查询¶
标量子查询是一个返回零行或一行的非相关子查询。 子查询产生多于一行的结果将是一个错误。 如果子查询产生零行,则返回值为 NULL
SELECT name
FROM nation
WHERE regionkey = (SELECT max(regionkey) FROM region)
注意
目前标量子查询只能返回单个列。