Examples
选择FROM
子句中存在的所有列:
SELECT * FROM table_name;
计算表中的行数:
SELECT count(*) FROM table_name;
DuckDB 为 count(*)
表达式提供了一种简写形式,其中 *
可以省略:
SELECT count() FROM table_name;
从名为 table_name
的表中选择所有列:
SELECT table_name.*
FROM table_name
JOIN other_table_name USING (id);
从地址表中选择除城市列之外的所有列:
SELECT * EXCLUDE (city)
FROM addresses;
从地址表中选择所有列,但将城市替换为 lower(city)
:
SELECT * REPLACE (lower(city) AS city)
FROM addresses;
选择所有匹配给定表达式的列:
SELECT COLUMNS(c -> c LIKE '%num%')
FROM addresses;
从表中选择所有匹配给定正则表达式的列:
SELECT COLUMNS('number\d+')
FROM addresses;
使用列表选择列:
SELECT COLUMNS(['city', 'zip_code'])
FROM addresses;
Syntax
Star Expression
*
表达式可以在 SELECT
语句中使用,以选择在 FROM
子句中投影的所有列。
SELECT *
FROM tbl;
*
表达式可以使用 EXCLUDE
和 REPLACE
进行修改。
EXCLUDE
子句
EXCLUDE
允许我们从 *
表达式中排除特定的列。
SELECT * EXCLUDE (col)
FROM tbl;
REPLACE
子句
REPLACE
允许我们根据表达式替换列中的特定值。
SELECT * REPLACE (col / 1_000 AS col)
FROM tbl;
COLUMNS
表达式
COLUMNS
表达式可以用于在多个列的值上执行相同的表达式。例如:
CREATE TABLE numbers (id INTEGER, number INTEGER);
INSERT INTO numbers VALUES (1, 10), (2, 20), (3, NULL);
SELECT min(COLUMNS(*)), count(COLUMNS(*)) FROM numbers;
编号 | 数字 | 编号 | 数字 |
---|---|---|---|
1 | 10 | 3 | 2 |
COLUMNS
语句中的 *
表达式也可以包含 EXCLUDE
或 REPLACE
,类似于常规的星号表达式。
SELECT
min(COLUMNS(* REPLACE (number + id AS number))),
count(COLUMNS(* EXCLUDE (number)))
FROM numbers;
id | min(number := (number + id)) | id |
---|---|---|
1 | 11 | 3 |
COLUMNS
表达式也可以组合使用,只要 COLUMNS
包含相同的(星号)表达式:
SELECT COLUMNS(*) + COLUMNS(*) FROM numbers;
编号 | 数字 |
---|---|
2 | 20 |
4 | 40 |
6 | NULL |
COLUMNS
表达式也可以用在 WHERE
子句中。条件会应用于所有列,并使用逻辑 AND
运算符进行组合。
SELECT *
FROM (
SELECT 0 AS x, 1 AS y, 2 AS z
UNION ALL
SELECT 1 AS x, 2 AS y, 3 AS z
UNION ALL
SELECT 2 AS x, 3 AS y, 4 AS z
)
WHERE COLUMNS(*) > 1; -- equivalent to: x > 1 AND y > 1 AND z > 1
x | y | z |
---|---|---|
2 | 3 | 4 |
COLUMNS
正则表达式
COLUMNS
支持将正则表达式作为字符串常量传递:
SELECT COLUMNS('(id|numbers?)') FROM numbers;
编号 | 数字 |
---|---|
1 | 10 |
2 | 20 |
3 | NULL |
使用COLUMNS
表达式重命名列
捕获组的匹配项可用于重命名通过正则表达式选择的列。
捕获组是从1开始索引的;\0
是原始列名。
例如,要选择列名的前三个字母,请运行:
SELECT COLUMNS('(\w{3}).*') AS '\1' FROM numbers;
id | num |
---|---|
1 | 10 |
2 | 20 |
3 | NULL |
要删除列名中间的冒号(:
)字符,请运行:
CREATE TABLE tbl ("Foo:Bar" INTEGER, "Foo:Baz" INTEGER, "Foo:Qux" INTEGER);
SELECT COLUMNS('(\w*):(\w*)') AS '\1\2' FROM tbl;
COLUMNS
Lambda 函数
COLUMNS
还支持传入一个 lambda 函数。该 lambda 函数将对 FROM
子句中存在的所有列进行评估,只有符合 lambda 函数的列才会被返回。这允许执行任意表达式以选择和重命名列。
SELECT COLUMNS(c -> c LIKE '%num%') FROM numbers;
数字 |
---|
10 |
20 |
NULL |
*COLUMNS
解包列
*COLUMNS
子句是 COLUMNS
的一种变体,它支持所有前面提到的功能。
区别在于表达式的扩展方式。
*COLUMNS
将会在原地展开,类似于 Python 中的可迭代对象解包行为,这启发了 *
语法的使用。
这意味着表达式会展开到父表达式中。
以下是一个展示 COLUMNS
和 *COLUMNS
之间区别的示例:
使用 COLUMNS
:
SELECT coalesce(COLUMNS(['a', 'b', 'c'])) AS result
FROM (SELECT NULL a, 42 b, true c);
结果 | 结果 | 结果 |
---|---|---|
NULL | 42 | true |
使用*COLUMNS
时,表达式在其父表达式coalesce
中展开,从而生成一个单一的结果列:
SELECT coalesce(*COLUMNS(['a', 'b', 'c'])) AS result
FROM (SELECT NULL AS a, 42 AS b, true AS c);
result |
---|
42 |
*COLUMNS
也可以与 (*)
参数一起使用:
SELECT coalesce(*COLUMNS(*)) AS result
FROM (SELECT NULL a, 42 AS b, true AS c);
result |
---|
42 |
STRUCT.*
*
表达式也可以用于从结构体中检索所有键作为单独的列。
这在先前的操作创建了一个未知形状的结构体,或者查询必须处理任何潜在的结构体键时特别有用。
有关处理结构体的更多详细信息,请参阅 STRUCT
数据类型 和 STRUCT
函数 页面。
例如:
SELECT st.* FROM (SELECT {'x': 1, 'y': 2, 'z': 3} AS st);
x | y | z |
---|---|---|
1 | 2 | 3 |