搜索快捷键 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
- MERGE INTO
- PIVOT
- 性能分析
- SELECT
- SET / RESET
- SET VARIABLE
- SHOW 与 SHOW DATABASES
- 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
- Lance
- MySQL
- PostgreSQL
- 空间
- SQLite
- TPC-DS
- TPC-H
- UI
- Unity Catalog
- Vortex
- 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 的占用空间
- 安装 DuckDB
- 日志
- 保护 DuckDB 安全
- 非确定性行为
- 限制
- DuckDB Docker 容器
- 开发
- 内部结构
- 站点地图
- 在线演示
文档 / SQL / DuckDB 的 SQL 方言
友好的 SQL
DuckDB 提供了一些高级 SQL 功能和语法糖,使 SQL 查询更加简洁。我们通俗地将其称为“友好 SQL”。
其中一些功能由 DuckDB 首先引入,而另一些则受到其他系统的启发。许多最初由 DuckDB 引入的功能(例如
GROUP BY ALL)后来已被其他系统采用。
子句
- 创建表和插入数据
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 ...:插入不会产生冲突的行。对于产生冲突的行,将现有行的列替换为待插入行的新值。
- 描述表和计算统计信息
- 使 SQL 子句更紧凑、更易读
FROM-first 语法(带有可选的SELECT子句):DuckDB 允许使用FROM tbl形式的查询,这将选择所有列(执行SELECT *语句)。GROUP BY ALL:省略 group-by 列,通过从SELECT子句中的属性列表推断得出。ORDER BY ALL:按所有列排序的简写(例如,确保结果确定性)。SELECT * EXCLUDE:EXCLUDE选项允许从*表达式中排除特定列。SELECT * REPLACE:REPLACE选项允许在*表达式中用不同的表达式替换特定列。UNION BY NAME:沿列名(而不是依赖位置)执行UNION操作。SELECT和FROM子句中的前缀别名:书写x: 42而非42 AS x,以提高可读性。- 为
LIMIT子句指定表大小的百分比:书写LIMIT 10%可返回查询结果的 10%。
- 转换表
- 定义 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 文件
- 替换扫描 (Replacement scans):
- 您可以使用语法
FROM 'my.csv',FROM 'my.csv.gz',FROM 'my.parquet'等从文件中加载数据。 - 在 Python 中,您可以使用
FROM df访问 Pandas 数据帧。
- 您可以使用语法
- 文件名扩展 (globbing),例如:
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”查询
计算按某种标准排序的“组内前 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 中 val 的前 3 大值。传统方法是在子查询中使用窗口函数
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] │
└─────────────┘