Only the Chinese version of this page is provided currently. The English version will be provided soon.
Help & Documentation>Data Lake Compute

标准 Presto 语法概览

Last updated: 2026-01-05 15:22:42

标准 Presto 引擎的内核基于 Presto 0.242 自研,兼容 Presto 原生语法和行为,适用于交互式查询分析。详细的语法请参考 Presto 语法文档。
说明:
presto 引擎已下线,仅供存量用户使用。
用途
语法
是否支持
备注
修改函数定义
ALTER FUNCTION

重命名 Schema
ALTER SCHEMA

修改数据表
ALTER TABLE
只支持 iceberg 表。
执行时需要通过三段式指定目标表的 Iceberg catalog 或者先执行 use iceberg.dbname
对数据表进行统计
ANALYZE
只支持 Hive 表
提交当前事务
COMMIT

创建函数
CREATE FUNCTION

创建角色
CREATE ROLE

创建 SCHEMA
CREATE SCHEMA

创建数据表
CREATE TABLE

使用 SELECT 建表
CREATE TABLE AS

创建视图
CREATE VIEW

删除 PREPARE
DEALLOCATE PREPARE

删除数据
DELETE

展示列信息
DESCRIBE

展示 PREPARE 输入信息
DESCRIBE INPUT

展示 PREPARE 输出信息
DESCRIBE OUTPUT

删除函数
DROP FUNCTION

删除角色
DROP ROLE

删除 SCHEMA
DROP SCHEMA

删除数据表
DROP TABLE

删除视图
DROP VIEW

执行 PREPARE
EXECUTE

展示执行 SQL 的逻辑或物理计划
EXPLAIN

执行 SQL 并展示执行计划
EXPLAIN ANALYZE

授权
GRANT

将角色授权给指定对象
GRANT ROLE

插入数据
INSERT
如果是 Iceberg 表,执行时需要通过三段式指定目标表的 iceberg catalog 或者先执行 use iceberg.dbname
创建 PREPARE
PREPARE

指定 SESSION 恢复默认值
RESET SESSION

取消授权
REVOKE

取消授予的角色
REVOKE ROLES

回滚事务
ROLLBACK

查询数据
SELECT

设置角色
SET ROLE

设置指定 SESSION 的值
SET SESSION

展示 CATALOG 列表
SHOW CATALOGS

展示表的列信息
SHOW COLUMNS

展示函数信息
SHOW CREATE FUNCTION

展示建表信息
SHOW CREATE TABLE

展示创建视图信息
SHOW CREATE VIEW

展示函数列表
SHOW FUNCTIONS

展示指定用户的权限
SHOW GRANTS

展示授权的角色列表
SHOW ROLE GRANTS
展示角色列表
SHOW ROLES

展示 SCHEMA 列表
SHOW SCHEMAS

展示 SESSION 列表
SHOW SESSION

展示表的统计信息
SHOW STATS
展示表列表
SHOW TABLES

开始事务
START TRANSACTION

删除表的所有内容
TRUNCATE

更新表的内容
UPDATE

指定默认 SCHEMA 或数据库
USE

定义内联表
VALUES



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 Clause

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;

GROUP BY Clause

GROUP BY子句将SELECT按照指定字段分组。
以下查询是等价的。它们都使用nationkey分组,第一个查询根据列的序号也就是第二列分组,而第二个查询直接使用列名:
SELECT count(*), nationkey FROM customer GROUP BY 2;

SELECT count(*), nationkey FROM customer GROUP BY nationkey;
也可以不查询分组字段:
SELECT count(*) FROM customer GROUP BY mktsegment;

_col0
-------
29968
30142
30189
29949
29752
(5 rows)

复杂分组操作

Presto还支持使用GROUPING SETS、CUBE和ROLLUP语法进行复杂的聚合操作。这种语法允许用户在单个查询中对多个列集进行聚合。
复杂的分组操作通常等同于简单的GROUP BY表达式的UNION ALL操作,如下面的示例所示。

GROUPING SETS

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;

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), ());

Combining multiple grouping expressions

在同一个查询中使用多个分组表达式会被解释为具有交叉乘积语义。例如,下面的查询:
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),
());

GROUPING Operation

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 Clause

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 Clause

UNION、INTERSECT和EXCEPT都是集合操作。这些子句用于将多个SELECT语句的结果合并为一个结果集:
query UNION [ALL | DISTINCT] query
query INTERSECT [DISTINCT] query
query EXCEPT [DISTINCT] query
参数ALL或DISTINCT控制哪些行包含在最终的结果集中。如果指定了参数ALL,即使行是相同的,所有行也会被包含在内。如果指定了参数DISTINCT,只有唯一的行会包含在合并的结果集中。如果没有指定任何参数,默认行为是DISTINCT。对于INTERSECT或EXCEPT,不支持参数ALL。
多个集合操作从左到右进行处理,除非通过括号明确指定顺序。此外,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 Clause

ORDER BY子句用于按一个或多个输出表达式对结果集进行排序。
每个表达式可以由输出列组成,也可以是一个序数,通过位置选择一个输出列(从1开始)。ORDER BY子句在任何GROUP BY或HAVING子句之后,在任何OFFSET、LIMIT或FETCH FIRST子句之前进行评估。默认的空值排序是NULLS LAST,无论排序方向如何。
ORDER BY expression [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...]

OFFSET Clause

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 Clause

LIMIT子句限制结果集中的行数。LIMIT ALL与省略LIMIT子句相同,表示不限制行数。
LIMIT { count | ALL }
以下示例查询一个大表,但是由于缺少ORDER BY子句,LIMIT子句将限制输出只有五行
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:

每行被选入表样本的概率是根据采样百分比确定的。当使用伯努利方法对表进行采样时,会扫描表的所有物理块,并根据在运行时计算的随机值与采样百分比进行比较,决定是否跳过某些行。每行是否包含在结果中的概率是独立于其他行的。这并不会减少从磁盘读取采样表所需的时间。如果对采样输出进行进一步处理,可能会对总查询时间产生影响。

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)展开为关系。数组展开为单列,映射展开为两列(键、值)。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 clause:
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)

-- 使用单个映射(MAP)列:
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

连接(Joins)允许您将来自多个关系的数据进行合并。

CROSS JOIN

一个交叉连接(Cross Join)返回两个关系的笛卡尔积(所有组合)。可以使用显式的CROSS JOIN语法或在FROM子句中指定多个关系来指定交叉连接。
以下两个查询是等价的:
SELECT *
FROM nation
CROSS JOIN region;

SELECT *
FROM nation, region;
The 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)

Qualifying Column Names

当连接中的两个关系具有相同名称的列时,必须使用关系别名(如果关系有别名)或关系名称来限定列引用:
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 nameFROM nationCROSS 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进行连接的输出将包括连接键列(在上面的示例中为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

用于确定子查询生成的任何值是否与提供的表达式相等。子查询必须生成恰好一列:
SELECT name
FROM nation
WHERE regionkey IN (SELECT regionkey FROM region)

标量子查询

标量子查询是一个非相关的子查询,它返回零行或一行。如果子查询产生多于一行的结果,将会报错。如果子查询没有返回任何行,返回的值将为NULL。
SELECT name
FROM nation
WHERE regionkey = (SELECT max(regionkey) FROM region)