- 安装
- 文档
- 入门
- 连接
- 数据导入与导出
- 湖仓格式
- 客户端 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 同时支持隐式类型转换和显式类型转换。
显式转换 (Explicit Casting)
显式类型转换通过使用 CAST 表达式来执行。例如,CAST(col AS VARCHAR) 或 col::VARCHAR 会将列 col 显式转换为 VARCHAR。有关更多信息,请参阅 cast 页面。
隐式转换 (Implicit Casting)
在许多情况下,系统会自动添加转换。这被称为隐式转换。例如,当函数被调用时,传入的参数类型与函数要求的类型不匹配,但可以转换为所需类型时,就会发生这种情况。
隐式转换仅适用于部分类型组合,且通常仅在转换不会失败的情况下才可能发生。例如,可以从 INTEGER 隐式转换为 DOUBLE,但不能从 DOUBLE 隐式转换为 INTEGER。
考虑函数 sin(DOUBLE)。该函数接收 DOUBLE 类型的列作为输入参数,但也可以使用整数进行调用:sin(1)。在传递给 sin 函数之前,该整数会被转换为 double 类型。
提示:要检查某种类型是否可以隐式转换为另一种类型,请使用
can_cast_implicitly函数。
组合转换 (Combination Casting)
当不同类型的值需要组合成一个未指定的共同父类型时,系统会执行隐式转换,自动选择一个父类型。例如,list_value(1::INT64, 1::UINT64) 会创建一个 INT128[] 类型的列表。在这种情况下执行的隐式转换有时比常规的隐式转换更宽松。例如,BOOL 值可以被转换为 INT(true 映射为 1,false 映射为 0),尽管这在常规隐式转换中是不可能的。
这种组合转换发生在比较运算 (= / < / >)、集合运算 (UNION / EXCEPT / INTERSECT) 以及嵌套类型构造函数 (list_value / [...] / MAP) 中。
转换操作矩阵
特定数据类型的值并不总是可以转换为任何任意目标数据类型。唯一的例外是 NULL 值——它总是可以在各种类型之间转换。下表描述了支持哪些转换。当允许隐式转换时,意味着也允许显式转换。

即使基于源数据类型和目标数据类型支持某种转换操作,也不一定意味着该转换操作在运行时一定会成功。
已弃用:在 0.10.0 版本之前,DuckDB 允许在函数绑定期间将任何类型隐式转换为
VARCHAR。0.10.0 版本引入了一项破坏性更改,不再允许隐式转换为VARCHAR。可以使用old_implicit_casting配置选项设置来恢复旧行为。但是,请注意此标志将在未来被弃用。
有损转换 (Lossy Casts)
允许执行导致精度损失的转换操作。例如,可以将带有小数部分的数值类型(如 DECIMAL、FLOAT 或 DOUBLE)显式转换为整数类型(如 INTEGER 或 BIGINT)。数值会被四舍五入。
SELECT CAST(3.1 AS INTEGER); -- 3
SELECT CAST(3.5 AS INTEGER); -- 4
SELECT CAST(-1.7 AS INTEGER); -- -2
溢出 (Overflows)
会导致值溢出的转换操作会抛出错误。例如,值 999 对于 TINYINT 数据类型来说太大。因此,尝试将该值转换为该类型会导致运行时错误。
SELECT CAST(999 AS TINYINT);
Conversion Error:
Type INT32 with value 999 can't be cast because the value is out of range for the destination type INT8
因此,即使支持从 INTEGER 到 TINYINT 的转换操作,该特定值也是无法转换的。TRY_CAST 可用于将值转换为 NULL,而不是抛出错误。
Varchar
VARCHAR 类型充当通用目标:任何任意类型的值总是可以转换为 VARCHAR 类型。此类型也用于在 shell 中显示值。
SELECT CAST(42.5 AS VARCHAR);
支持从 VARCHAR 转换为其他数据类型,但如果 DuckDB 无法解析并将提供的文本转换为目标数据类型,则可能会在运行时引发错误。
SELECT CAST('NotANumber' AS INTEGER);
通常,转换为 VARCHAR 是一种无损操作,任何类型在转换为文本后都可以转换回原始类型。
SELECT CAST(CAST([1, 2, 3] AS VARCHAR) AS INTEGER[]);
字面量类型
整数常量(如 42)和字符串常量(如 'string')具有特殊的隐式转换规则。有关更多信息,请参阅 常量类型页面。
列表 / 数组 (Lists / Arrays)
列表可以使用相同的转换规则显式转换为其他列表。转换应用于列表的子元素。例如,如果我们转换一个 INTEGER[] 列表到一个 VARCHAR[] 列表,其中的 INTEGER 子元素会被逐个转换为 VARCHAR 并构建成一个新的列表。
SELECT CAST([1, 2, 3] AS VARCHAR[]);
数组 (Arrays)
数组遵循与列表相同的转换规则。此外,数组可以隐式转换为相同类型的列表。例如,INTEGER[3] 数组可以隐式转换为 INTEGER[] 列表。
结构体 (Structs)
只要结构体至少共享一个字段,就可以将它们转换为其他结构体。
此要求的初衷是为了避免意外错误。如果两个结构体没有任何共同字段,那么该转换很可能并非预期的。
SELECT CAST({'a': 42} AS STRUCT(a VARCHAR));
目标结构体中存在但源结构体中不存在的字段,默认设为 NULL。
SELECT CAST({'a': 42} AS STRUCT(a VARCHAR, b VARCHAR));
仅存在于源结构体中的字段将被忽略。
SELECT CAST({'a': 42, 'b': 43} AS STRUCT(a VARCHAR));
结构体的名称顺序也可以不同。结构体的字段将根据其名称进行重新排列。
SELECT CAST({'a': 42, 'b': 84} AS STRUCT(b VARCHAR, a VARCHAR));
对于组合转换,结果结构体的字段是所有输入结构体字段的并集。此逻辑也递归地适用于潜在的嵌套结构体。
SELECT {'outer1': {'inner1': 42, 'inner2': 42}} AS c
UNION
SELECT {'outer1': {'inner2': 'hello', 'inner3': 'world'}, 'outer2': '100'} AS c;
SELECT [{'a': 42}, {'b': 84}];
联合体 (Unions)
联合体的转换规则可以在 UNION 类型页面 上找到。