语法
* 表达式可以在 SELECT 语句中使用,以选择 FROM 子句中投影的所有列。
SELECT *
FROM tbl;
TABLE.* 和 STRUCT.*
* 表达式前可以加上表名,以仅选择该表中的列。
SELECT tbl.*
FROM tbl
JOIN other_tbl USING (id);
类似地,* 表达式也可用于将结构体(struct)中的所有键检索为单独的列。当先前的操作创建了一个未知结构的结构体,或者查询必须处理任何潜在的结构体键时,这尤其有用。有关处理结构体的更多详细信息,请参阅 STRUCT 数据类型 和 STRUCT 函数 页面。
例如
SELECT st.* FROM (SELECT {'x': 1, 'y': 2, 'z': 3} AS st);
| x | y | z |
|---|---|---|
| 1 | 2 | 3 |
EXCLUDE 子句
EXCLUDE 允许你从 * 表达式中排除特定的列。
SELECT * EXCLUDE (col)
FROM tbl;
REPLACE 子句
REPLACE 允许你用替代表达式替换特定的列。
SELECT * REPLACE (col1 / 1_000 AS col1, col2 / 1_000 AS col2)
FROM tbl;
RENAME 子句
RENAME 允许你重命名特定的列。
SELECT * RENAME (col1 AS height, col2 AS width)
FROM tbl;
通过模式匹配运算符进行列过滤
模式匹配运算符 LIKE、GLOB、SIMILAR TO 及其变体允许你通过将列名与模式匹配来选择列。
SELECT * LIKE 'col%'
FROM tbl;
SELECT * GLOB 'col*'
FROM tbl;
SELECT * SIMILAR TO '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;
| id | number | id | number |
|---|---|---|---|
| 1 | 10 | 3 | 2 |
SELECT
min(COLUMNS(* REPLACE (number + id AS number))),
count(COLUMNS(* EXCLUDE (number)))
FROM numbers;
| id | min(number := (number + id)) | id |
|---|---|---|
| 1 | 11 | 3 |
COLUMNS 表达式也可以组合使用,只要它们包含相同的星号表达式即可。
SELECT COLUMNS(*) + COLUMNS(*) FROM numbers;
| id | number |
|---|---|
| 2 | 20 |
| 4 | 40 |
| 6 | NULL |
WHERE 子句中的 COLUMNS 表达式
COLUMNS 表达式也可以在 WHERE 子句中使用。条件将应用于所有列,并使用逻辑 AND 运算符进行组合。
SELECT *
FROM (
SELECT 'a', 'a'
UNION ALL
SELECT 'a', 'b'
UNION ALL
SELECT 'b', 'b'
) _(x, y)
WHERE COLUMNS(*) = 'a'; -- equivalent to: x = 'a' AND y = 'a'
| x | y |
|---|---|
| a | a |
若要使用逻辑 OR 运算符组合条件,你可以将 COLUMNS 表达式 UNPACK(解包)到可变参数函数 greatest 中。
SELECT *
FROM (
SELECT 'a', 'a'
UNION ALL
SELECT 'a', 'b'
UNION ALL
SELECT 'b', 'b'
) _(x, y)
WHERE greatest(UNPACK(COLUMNS(*) = 'a')); -- equivalent to: x = 'a' OR y = 'a'
| x | y |
|---|---|
| a | a |
| a | b |
COLUMNS 表达式中的正则表达式
COLUMNS 表达式目前不支持模式匹配运算符,但它们支持通过直接传递字符串常量来代替星号进行正则表达式匹配。
SELECT COLUMNS('(id|numbers?)') FROM numbers;
| id | number |
|---|---|
| 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;
要将原始列名添加到表达式别名中,请运行
SELECT min(COLUMNS(*)) AS "min_\0" FROM numbers;
| min_id | min_number |
|---|---|
| 1 | 10 |
COLUMNS Lambda 函数
COLUMNS 还支持传入 Lambda 函数。Lambda 函数将针对 FROM 子句中存在的所有列进行评估,并且仅返回与 Lambda 函数匹配的列。这允许执行任意表达式来选择和重命名列。
SELECT COLUMNS(lambda c: c LIKE '%num%') FROM numbers;
| number |
|---|
| 10 |
| 20 |
| NULL |
COLUMNS 列表
COLUMNS 还支持传入列名列表。
SELECT COLUMNS(['id', 'num']) FROM numbers;
| id | num |
|---|---|
| 1 | 10 |
| 2 | 20 |
| 3 | NULL |
解包(Unpacking)COLUMNS 表达式
通过将 COLUMNS 表达式包装在 UNPACK 中,这些列会展开到父表达式中,非常类似于 Python 中的可迭代对象解包行为。
如果没有 UNPACK,对 COLUMNS 表达式的操作将分别应用于每一列。
SELECT coalesce(COLUMNS(['a', 'b', 'c'])) AS result
FROM (SELECT NULL a, 42 b, true c);
| 结果 | 结果 | 结果 |
|---|---|---|
| NULL | 42 | true |
使用 UNPACK 后,COLUMNS 表达式被展开到其父表达式(上述示例中的 coalesce)中,从而生成单一列。
SELECT coalesce(UNPACK(COLUMNS(['a', 'b', 'c']))) AS result
FROM (SELECT NULL AS a, 42 AS b, true AS c);
| 结果 |
|---|
| 42 |
当 UNPACK 关键字直接应用于 COLUMNS 表达式且没有任何中间操作时,可以用 * 替换它(匹配 Python 语法)。
SELECT coalesce(*COLUMNS(*)) AS result
FROM (SELECT NULL a, 42 AS b, true AS c);
| 结果 |
|---|
| 42 |
警告:在以下示例中,用
*替换UNPACK会导致语法错误。SELECT greatest(UNPACK(COLUMNS(*) + 1)) AS result FROM (SELECT 1 AS a, 2 AS b, 3 AS c);
结果 4
STRUCT.*
* 表达式也可用于将结构体中的所有键检索为单独的列。当先前的操作创建了一个未知结构的结构体,或者查询必须处理任何潜在的结构体键时,这尤其有用。有关处理结构体的更多详细信息,请参阅 STRUCT 数据类型 和 STRUCT 函数 页面。
例如
SELECT st.* FROM (SELECT {'x': 1, 'y': 2, 'z': 3} AS st);
| x | y | z |
|---|---|---|
| 1 | 2 | 3 |