搜索快捷键 cmd + k | ctrl + k
- 安装
- 文档
- 入门
- 连接
- 数据导入
- 客户端 API
- 概览
- ADBC
- C
- C++
- CLI
- Dart
- Go
- Java (JDBC)
- Julia
- Node.js (已弃用)
- Node.js (Neo)
- ODBC
- PHP
- Python
- R
- Rust
- Swift
- Wasm
- SQL
- 介绍
- 语句
- 概览
- ANALYZE
- ALTER TABLE
- ALTER VIEW
- ATTACH 和 DETACH
- CALL
- CHECKPOINT
- COMMENT ON
- COPY
- CREATE INDEX
- CREATE MACRO
- CREATE SCHEMA
- CREATE SECRET
- CREATE SEQUENCE
- CREATE TABLE
- CREATE VIEW
- CREATE TYPE
- DELETE
- DESCRIBE
- DROP
- EXPORT 和 IMPORT DATABASE
- INSERT
- LOAD / INSTALL
- PIVOT
- 性能分析
- SELECT
- SET / RESET
- SET VARIABLE
- SUMMARIZE
- 事务管理
- UNPIVOT
- UPDATE
- USE
- VACUUM
- 查询语法
- SELECT
- FROM 和 JOIN
- WHERE
- GROUP BY
- GROUPING SETS
- HAVING
- ORDER BY
- LIMIT 和 OFFSET
- SAMPLE
- 展开嵌套
- WITH
- WINDOW
- QUALIFY
- VALUES
- FILTER
- 集合操作
- 预处理语句
- 数据类型
- 表达式
- 函数
- 概览
- 聚合函数
- 数组函数
- 位字符串函数
- Blob 函数
- 日期格式化函数
- 日期函数
- 日期部分函数
- 枚举函数
- 间隔函数
- Lambda 函数
- 列表函数
- 映射函数
- 嵌套函数
- 数值函数
- 模式匹配
- 正则表达式
- 结构体函数
- 文本函数
- 时间函数
- 时间戳函数
- 带时区时间戳函数
- 联合函数
- 实用函数
- 窗口函数
- 约束
- 索引
- 元查询
- DuckDB 的 SQL 方言
- 示例
- 配置
- 扩展
- 核心扩展
- 概览
- 自动补全
- Avro
- AWS
- Azure
- Delta
- DuckLake
- 编码
- Excel
- 全文搜索
- httpfs (HTTP 和 S3)
- Iceberg
- ICU
- inet
- jemalloc
- MySQL
- PostgreSQL
- 空间
- SQLite
- TPC-DS
- TPC-H
- UI
- VSS
- 指南
- 概览
- 数据查看器
- 数据库集成
- 文件格式
- 概览
- CSV 导入
- CSV 导出
- 直接读取文件
- Excel 导入
- Excel 导出
- JSON 导入
- JSON 导出
- Parquet 导入
- Parquet 导出
- 查询 Parquet 文件
- 使用 file: 协议访问文件
- 网络和云存储
- 概览
- HTTP Parquet 导入
- S3 Parquet 导入
- S3 Parquet 导出
- S3 Iceberg 导入
- S3 Express One
- GCS 导入
- Cloudflare R2 导入
- 通过 HTTPS / S3 使用 DuckDB
- Fastly 对象存储导入
- 元查询
- ODBC
- 性能
- Python
- 安装
- 执行 SQL
- Jupyter Notebooks
- marimo Notebooks
- Pandas 上的 SQL
- 从 Pandas 导入
- 导出到 Pandas
- 从 Numpy 导入
- 导出到 Numpy
- Arrow 上的 SQL
- 从 Arrow 导入
- 导出到 Arrow
- Pandas 上的关系型 API
- 多个 Python 线程
- 与 Ibis 集成
- 与 Polars 集成
- 使用 fsspec 文件系统
- SQL 编辑器
- SQL 功能
- 代码片段
- 故障排除
- 术语表
- 离线浏览
- 操作手册
- 开发
- 内部结构
- 为什么选择 DuckDB
- 行为准则
- 发布日历
- 路线图
- 站点地图
- 在线演示
文档 / SQL / DuckDB 的 SQL 方言
友好的 SQL
DuckDB 提供了一些高级 SQL 特性和语法糖,使 SQL 查询更简洁。我们通俗地称之为“友好型 SQL”。
其中一些特性也受其他系统支持,而有些(目前)是 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
约束而导致冲突的行。对于发生冲突的行,将现有行的列替换为待插入行的新值。
- 描述表和计算统计信息
- 使 SQL 子句更紧凑和可读
- 以
FROM
为先的语法,带可选的SELECT
子句:DuckDB 允许使用FROM tbl
形式的查询,它会选择所有列(执行SELECT *
语句)。 GROUP BY ALL
:通过从SELECT
子句中的属性列表推断,省略分组列。ORDER BY ALL
:对所有列进行排序的简写(例如,确保确定性结果)。SELECT * EXCLUDE
:EXCLUDE
选项允许从*
表达式中排除特定列。SELECT * REPLACE
:REPLACE
选项允许在*
表达式中用不同的表达式替换特定列。UNION BY NAME
:根据列名执行UNION
操作(而不是依赖于位置)。- 在
SELECT
和FROM
子句中使用前缀别名:写x: 42
而不是42 AS x
以提高可读性。
- 以
- 转换表
- 定义 SQL 级变量
查询特性
- 在
WHERE
、GROUP BY
和HAVING
中使用列别名。(请注意,列别名不能用于JOIN
子句的ON
子句中。) COLUMNS()
表达式可用于在多列上执行相同的表达式- 可重用列别名(也称为“侧向列别名”),例如:
SELECT i + 1 AS j, j + 2 AS k FROM range(0, 3) t(i)
- 用于分析 (OLAP) 查询的高级聚合功能
count()
简写,等同于count(*)
- 用于列表和映射的
IN
运算符 - 为公共表表达式 (
WITH
) 指定列名 - 在
JOIN
子句中指定列名 - 在
JOIN
子句中使用VALUES
- 在公共表表达式的锚点部分使用
VALUES
字面量和标识符
数据类型
数据导入
- 自动检测 CSV 文件的头部和模式
- 直接查询 CSV 文件和 Parquet 文件
- 替换扫描:
- 您可以使用
FROM 'my.csv'
、FROM 'my.csv.gz'
、FROM 'my.parquet'
等语法从文件加载。 - 在 Python 中,您可以使用
FROM df
访问 Pandas 数据帧。
- 您可以使用
- 文件名展开(通配),例如:
FROM 'my-data/part-*.parquet'
函数和表达式
- 用于函数链式调用的点运算符:
SELECT ('hello').upper()
- 字符串格式化器:使用
fmt
语法的format()
函数和printf()
函数 - 列表推导
- 列表切片和从末尾索引 (
[-1]
) - 字符串切片
STRUCT.*
符号- 使用方括号创建
LIST
- 简单的
LIST
和STRUCT
创建 - 更新
STRUCT
的模式
连接类型
尾随逗号
DuckDB 允许使用尾随逗号,无论是在列出实体(例如列名和表名)时,还是在构造LIST
项时。例如,以下查询有效
SELECT
42 AS x,
['a', 'b', 'c',] AS y,
'hello world' AS z,
;
“组内 Top-N”查询
计算按某些条件排序的“组内 Top-N 行”是 SQL 中常见的任务,但遗憾的是,它通常需要涉及窗口函数和/或子查询的复杂查询。
为帮助解决此问题,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] │
└─────────────┘
相关博客文章
- “DuckDB 的友好型 SQL” 博客文章
- “DuckDB 进一步友好的 SQL” 博客文章
- “SQL 技巧:将 SQL 塑造出灵活的新形态” 博客文章