标准 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 ] JOINLEFT [ OUTER ] JOINRIGHT [ OUTER ] JOINFULL [ OUTER ] JOINCROSS JOIN
grouping_element:
()expressionGROUPING SETS ( ( column [, ...] ) [, ...] )CUBE ( column [, ...] )ROLLUP ( column [, ...] )
示例
WITH Clause
WITH子句定义了在查询中使用的命名关系。它允许扁平化嵌套查询或简化子查询。例如,以下查询是等价的:
SELECT a, bFROM (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;
也适用于多个子查询:
WITHt1 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 t1JOIN t2 ON t1.a = t2.a;
此外,WITH子句中的关系可以连接:
WITHx 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-------2996830142301892994929752(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 | 13California | 94131 | New Jersey | 8540 | 42New Jersey | 7081 | Connecticut | 6708 | 225California | 90210 | Connecticut | 6927 | 1337California | 94131 | Colorado | 80302 | 5New York | 10002 | New Jersey | 8540 | 3(6 rows)
GROUPING SETS的语义可以通过以下示例查询来演示:
SELECT origin_state, origin_zip, destination_state, sum(package_weight)FROM shippingGROUP BY GROUPING SETS ((origin_state),(origin_state, origin_zip),(destination_state));origin_state | origin_zip | destination_state | _col0--------------+------------+-------------------+-------New Jersey | NULL | NULL | 225California | NULL | NULL | 1397New York | NULL | NULL | 3California | 90210 | NULL | 1337California | 94131 | NULL | 60New Jersey | 7081 | NULL | 225New York | 10002 | NULL | 3NULL | NULL | Colorado | 5NULL | NULL | New Jersey | 58NULL | NULL | Connecticut | 1562(10 rows)
前面的查询在逻辑上可以被视为多个GROUP BY查询的UNION ALL的等价形式:
SELECT origin_state, NULL, NULL, sum(package_weight)FROM shipping GROUP BY origin_stateUNION ALLSELECT origin_state, origin_zip, NULL, sum(package_weight)FROM shipping GROUP BY origin_state, origin_zipUNION ALLSELECT NULL, NULL, destination_state, sum(package_weight)FROM shipping GROUP BY destination_state;
CUBE
CUBE运算符为给定的列集生成所有可能的分组集合(即幂集)。它允许您对各种列的组合进行聚合。例如,考虑以下查询:
SELECT origin_state, destination_state, sum(package_weight)FROM shippingGROUP BY CUBE (origin_state, destination_state);-- 等价于:SELECT origin_state, destination_state, sum(package_weight)FROM shippingGROUP BY GROUPING SETS ((origin_state, destination_state),(origin_state),(destination_state),());origin_state | destination_state | _col0--------------+-------------------+-------California | New Jersey | 55California | Colorado | 5New York | New Jersey | 3New Jersey | Connecticut | 225California | Connecticut | 1337California | NULL | 1397New York | NULL | 3New Jersey | NULL | 225NULL | New Jersey | 58NULL | Connecticut | 1562NULL | Colorado | 5NULL | NULL | 1625(12 rows)
ROLLUP
ROLLUP运算符为给定的列集生成所有可能的小计。例如,考虑以下查询:
SELECT origin_state, origin_zip, sum(package_weight)FROM shippingGROUP BY ROLLUP (origin_state, origin_zip);origin_state | origin_zip | _col2--------------+------------+-------California | 94131 | 60California | 90210 | 1337New Jersey | 7081 | 225New York | 10002 | 3California | NULL | 1397New York | NULL | 3New Jersey | NULL | 225NULL | NULL | 1625(8 rows)-- 等价于:SELECT origin_state, origin_zip, sum(package_weight)FROM shippingGROUP BY GROUPING SETS ((origin_state, origin_zip), (origin_state), ());
Combining multiple grouping expressions
在同一个查询中使用多个分组表达式会被解释为具有交叉乘积语义。例如,下面的查询:
SELECT origin_state, destination_state, origin_zip, sum(package_weight)FROM shippingGROUP BYGROUPING SETS ((origin_state, destination_state)),ROLLUP (origin_zip);-- 可重写为:SELECT origin_state, destination_state, origin_zip, sum(package_weight)FROM shippingGROUP BYGROUPING SETS ((origin_state, destination_state)),GROUPING SETS ((origin_zip), ());-- 逻辑上等价于:SELECT origin_state, destination_state, origin_zip, sum(package_weight)FROM shippingGROUP 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 | 3California | New Jersey | 94131 | 55New Jersey | Connecticut | 7081 | 225California | Connecticut | 90210 | 1337California | Colorado | 94131 | 5New York | New Jersey | NULL | 3New Jersey | Connecticut | NULL | 225California | Colorado | NULL | 5California | Connecticut | NULL | 1337California | New Jersey | NULL | 55(10 rows)
ALL和DISTINCT量词确定重复的分组集是否会产生不同的输出行。当在同一个查询中组合多个复杂的分组集时,这特别有用。例如,下面的查询:
SELECT origin_state, destination_state, origin_zip, sum(package_weight)FROM shippingGROUP BY ALLCUBE (origin_state, destination_state),ROLLUP (origin_state, origin_zip);-- 等价于:SELECT origin_state, destination_state, origin_zip, sum(package_weight)FROM shippingGROUP 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 shippingGROUP BY DISTINCTCUBE (origin_state, destination_state),ROLLUP (origin_state, origin_zip);-- 只会生成唯一的分组集合:SELECT origin_state, destination_state, origin_zip, sum(package_weight)FROM shippingGROUP 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 shippingGROUP BY GROUPING SETS ((origin_state),(origin_state, origin_zip),(destination_state));origin_state | origin_zip | destination_state | _col3 | _col4--------------+------------+-------------------+-------+-------California | NULL | NULL | 1397 | 3New Jersey | NULL | NULL | 225 | 3New York | NULL | NULL | 3 | 3California | 94131 | NULL | 60 | 1New Jersey | 7081 | NULL | 225 | 1California | 90210 | NULL | 1337 | 1New York | 10002 | NULL | 3 | 1NULL | NULL | New Jersey | 58 | 6NULL | NULL | Connecticut | 1562 | 6NULL | 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 totalbalFROM customerGROUP BY mktsegment, nationkeyHAVING sum(acctbal) > 5700000ORDER BY totalbal DESC;_col0 | mktsegment | nationkey | totalbal-------+------------+-----------+----------1272 | AUTOMOBILE | 19 | 58569391253 | FURNITURE | 14 | 57948871248 | FURNITURE | 9 | 57846281243 | FURNITURE | 12 | 57573711231 | HOUSEHOLD | 3 | 57532161251 | MACHINERY | 2 | 57191401247 | FURNITURE | 8 | 5701952(7 rows)
UNION | INTERSECT | EXCEPT Clause
UNION、INTERSECT和EXCEPT都是集合操作。这些子句用于将多个SELECT语句的结果合并为一个结果集:
query UNION [ALL | DISTINCT] queryquery INTERSECT [DISTINCT] queryquery 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 13UNIONSELECT 42;_col0-------1342(2 rows)
以下查询演示了UNION和UNION ALL之间的区别。它选择值13,并将此结果集与选择值42和13的第二个查询结果集合并在一起:
SELECT 13UNIONSELECT * FROM (VALUES 42, 13);_col0-------1342(2 rows)------------------------------------SELECT 13UNION ALLSELECT * FROM (VALUES 42, 13);_col0-------134213(2 rows)
INTERSECT
INTERSECT仅返回同时存在于第一个查询和第二个查询结果集中的行。以下是一个最简单的INTERSECT子句示例。它选择值13和42,并将此结果集与选择值13的第二个查询结果集合并在一起。由于42只存在于第一个查询的结果集中,它不会包含在最终结果中:
SELECT * FROM (VALUES 13, 42)INTERSECTSELECT 13;_col0-------13(2 rows)
EXCEPT
EXCEPT返回第一个查询结果集中存在但不在第二个查询结果集中的行。以下是一个最简单的EXCEPT子句示例。它选择值13和42,并将此结果集与选择值13的第二个查询结果集合并在一起。由于13也存在于第二个查询的结果集中,它不会包含在最终结果中:
SELECT * FROM (VALUES 13, 42)EXCEPTSELECT 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 KINGDOMUNITED STATESVIETNAM(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-141992-01-151995-02-011995-11-121992-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---34(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, scoreFROM testsCROSS JOIN UNNEST(scores) AS t (score);-- 使用多个数组列SELECT numbers, animals, n, aFROM (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, aFROM (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)列:SELECTanimals, a, nFROM (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 nationCROSS JOIN region;SELECT *FROM nation, region;
The nation表包含25行,而region表包含5行,因此两个表之间的交叉连接将产生125行:
SELECT n.name AS nation, r.name AS regionFROM nation AS nCROSS JOIN region AS rORDER BY 1, 2;nation | region----------------+-------------ALGERIA | AFRICAALGERIA | AMERICAALGERIA | ASIAALGERIA | EUROPEALGERIA | MIDDLE EASTARGENTINA | AFRICAARGENTINA | AMERICA...(125 rows)
Qualifying Column Names
当连接中的两个关系具有相同名称的列时,必须使用关系别名(如果关系有别名)或关系名称来限定列引用:
SELECT nation.name, region.nameFROM nationCROSS JOIN region;SELECT n.name, r.nameFROM nation AS nCROSS JOIN region AS r;SELECT n.name, r.nameFROM nation nCROSS JOIN region r;
以下查询将失败,并显示错误消息“Column 'name' is ambiguous”:
SELECT nameFROM nationCROSS JOIN region;
USING
使用USING子句可以在连接的两个表具有相同的连接键名称时编写更简短的查询。
例如:
SELECT *FROM table_1JOIN table_2ON table_1.key_A = table_2.key_A AND table_1.key_B = table_2.key_B-- 可以重写为:SELECT *FROM table_1JOIN table_2USING (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 | 1002 | 4 | 20 | 200(2 rows)
子查询
一个子查询是由一个查询组成的表达式。当子查询引用子查询外的列时,它被称为相关子查询。
EXISTS
EXISTS用于确定子查询是否返回任何行:
SELECT nameFROM nationWHERE EXISTS (SELECT * FROM region WHERE region.regionkey = nation.regionkey)
IN
用于确定子查询生成的任何值是否与提供的表达式相等。子查询必须生成恰好一列:
SELECT nameFROM nationWHERE regionkey IN (SELECT regionkey FROM region)
标量子查询
标量子查询是一个非相关的子查询,它返回零行或一行。如果子查询产生多于一行的结果,将会报错。如果子查询没有返回任何行,返回的值将为NULL。
SELECT nameFROM nationWHERE regionkey = (SELECT max(regionkey) FROM region)