Note
这些特性中的一些在其他系统中也得到支持,而有些(目前)是DuckDB独有的。
DuckDB 提供了几种高级 SQL 功能和语法糖,以使 SQL 查询更加简洁。我们通常将这些称为“友好的 SQL”。
Note
这些特性中的一些在其他系统中也得到支持,而有些(目前)是DuckDB独有的。
CREATE OR REPLACE TABLE
: 避免在脚本中使用 DROP TABLE IF EXISTS
语句。CREATE TABLE ... AS SELECT
(CTAS): 从表的输出中创建一个新表,而无需手动定义模式。INSERT INTO ... BY NAME
: 这种 INSERT
语句的变体允许使用列名而不是位置。INSERT OR IGNORE INTO ...
: 插入不会因 UNIQUE
或 PRIMARY KEY
约束而导致冲突的行。INSERT OR REPLACE INTO ...
: 插入不会因 UNIQUE
或 PRIMARY KEY
约束而导致冲突的行。对于导致冲突的行,将现有行的列替换为要插入行的新值。FROM
-first syntax with an optional SELECT
clause: DuckDB允许以FROM tbl
形式进行查询,选择所有列(执行SELECT *
语句)。GROUP BY ALL
: 通过从SELECT
子句中的属性列表推断分组列,省略分组列。ORDER BY ALL
: 对所有列进行排序的简写(例如,确保确定性结果)。SELECT * EXCLUDE
: EXCLUDE
选项允许从*
表达式中排除特定列。SELECT * REPLACE
: REPLACE
选项允许在*
表达式中用不同的表达式替换特定列。UNION BY NAME
: 根据列名执行UNION
操作(而不是依赖位置)。WHERE
、GROUP BY
和HAVING
中的列别名。(请注意,列别名不能在JOIN
子句的ON
子句中使用。)COLUMNS()
表达式 可以用于在多个列上执行相同的表达式:
SELECT i + 1 AS j, j + 2 AS k FROM range(0, 3) t(i)
count()
简写 用于 count(*)
FROM 'my.csv'
, FROM 'my.csv.gz'
, FROM 'my.parquet'
等从文件加载。FROM 'my-data/part-*.parquet'
SELECT ('hello').upper()
format()
函数与 fmt
语法 和
printf() 函数
STRUCT.*
表示法LIST
和 STRUCT
创建DuckDB 允许在列出实体(例如列名和表名)以及构建 LIST
项 时使用 尾随逗号。
例如,以下查询有效:
SELECT
42 AS x,
['a', 'b', 'c',] AS y,
'hello world' AS z,
;
在SQL中,按某些标准计算“组中的前N行”是一个常见任务,不幸的是,这通常需要一个涉及窗口函数和/或子查询的复杂查询。
为了帮助实现这一点,DuckDB 提供了聚合函数 max(arg, n)
, min(arg, n)
, arg_max(arg, val, n)
, arg_min(arg, val, n)
, max_by(arg, val, n)
和 min_by(arg, val, n)
,以高效地返回基于特定列的升序或降序排列的组中的“前”n
行。
例如,我们使用以下表格:
SELECT * FROM t1;
┌─────────┬───────┐
│ grp │ val │
│ varchar │ int32 │
├─────────┼───────┤
│ a │ 2 │
│ a │ 1 │
│ b │ 5 │
│ b │ 4 │
│ a │ 3 │
│ b │ 6 │
└─────────┴───────┘
我们想要获取每个组grp
中前3个val
值的列表。传统的方法是在子查询中使用窗口函数:
SELECT array_agg(rs.val), rs.grp
FROM
(SELECT val, grp, row_number() OVER (PARTITION BY grp ORDER BY val DESC) AS rid
FROM t1 ORDER BY val DESC) AS rs
WHERE rid < 4
GROUP BY rs.grp;
┌───────────────────┬─────────┐
│ array_agg(rs.val) │ grp │
│ int32[] │ varchar │
├───────────────────┼─────────┤
│ [3, 2, 1] │ a │
│ [6, 5, 4] │ b │
└───────────────────┴─────────┘
但在DuckDB中,我们可以更简洁(且高效!)地完成这个操作:
SELECT max(val, 3) FROM t1 GROUP BY grp;
┌─────────────┐
│ max(val, 3) │
│ int32[] │
├─────────────┤
│ [3, 2, 1] │
│ [6, 5, 4] │
└─────────────┘