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 语句输出中的输入列名对输出进行分组。例如,以下查询使用输入列 mktsegmentcustomer 表生成行计数

SELECT count(*) FROM customer GROUP BY mktsegment;
 _col0
-------
 29968
 30142
 30189
 29949
 29752
(5 rows)

GROUP BY 子句用于 SELECT 语句中时,所有输出表达式必须是聚合函数或存在于 GROUP BY 子句中的列。

复杂分组操作

Presto 还支持使用 GROUPING SETSCUBEROLLUP 语法的复杂聚合。此语法允许用户执行需要在单个查询中对多个列集进行聚合的分析。复杂分组操作不支持对由输入列组成的表达式进行分组。只允许使用列名或序数。

复杂分组操作通常等效于 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 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 子句

UNION INTERSECTEXCEPT 都是集合运算。这些子句用于将多个 select 语句的结果组合到一个结果集中

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

参数 ALLDISTINCT 控制哪些行包含在最终结果集中。如果指定参数 ALL,则即使行相同也会包含所有行。如果指定参数 DISTINCT,则仅将唯一行包含在组合结果集中。如果没有指定,则行为默认为 DISTINCT。参数 ALL 不支持 INTERSECTEXCEPT

多个集合运算从左到右处理,除非通过括号显式指定顺序。此外, INTERSECTEXCEPTUNION 绑定更紧密。这意味着 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 } ] [, ...]

每个表达式可以由输出列组成,也可以是按位置选择输出列的序数(从 1 开始)。 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

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_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 的结果遵循空值的标准规则。 子查询必须产生正好一列

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

标量子查询

标量子查询是一个返回零行或一行的非相关子查询。 子查询产生多于一行的结果将是一个错误。 如果子查询产生零行,则返回值为 NULL

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

注意

目前标量子查询只能返回单个列。