语法
* 表达式可以在 SELECT 语句中使用,以选择 FROM 子句中投影的所有列。
SELECT *
FROM tbl;
TABLE.* and STRUCT.*
* 表达式可以在表名前面加上,以仅选择该表中的列。
SELECT table_name.*
FROM table_name
JOIN other_table_name USING (id);
类似地,* 表达式也可以用于将结构体中的所有键作为单独的列检索出来。当之前的操作创建了一个未知形状的结构体,或者查询必须处理任何潜在的结构体键时,这尤其有用。有关使用结构体的更多详细信息,请参阅 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 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;
| 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(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 |
*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);
| 结果 |
|---|
| 42 |
*COLUMNS 也适用于 (*) 参数。
SELECT coalesce(*COLUMNS(*)) AS result
FROM (SELECT NULL a, 42 AS b, true AS c);
| 结果 |
|---|
| 42 |
STRUCT.*
* 表达式也可以用于将结构体中的所有键作为单独的列检索出来。当之前的操作创建了一个未知形状的结构体,或者查询必须处理任何潜在的结构体键时,这尤其有用。有关使用结构体的更多详细信息,请参阅 STRUCT 数据类型和 STRUCT 函数页面。
例如
SELECT st.* FROM (SELECT {'x': 1, 'y': 2, 'z': 3} AS st);
| x | y | z |
|---|---|---|
| 1 | 2 | 3 |