加载CSV至DuckDB时,如何避免numeric列自动追加.0?
DuckDB加载CSV后NUMERIC列显示.0的原因及解决办法
问题重现
你有一个两列的CSV文件:
col1,col2 10,20 11,21
通过以下DuckDB代码加载到表中,定义col2为numeric类型:
conn = duckdb.connect() cur = conn.cursor() query1 = "create schema public;CREATE TABLE IF NOT EXISTS public.temp(col1 integer,col2 numeric)" query2 = "COPY public.temp FROM '/Users/data.csv' WITH (FORMAT csv, HEADER true)" cur.execute(query1) cur.execute(query2) conn.commit()
加载后查询发现col2显示为20.0、21.0,而PostgreSQL中相同操作会显示为整数。
原因
这是DuckDB和PostgreSQL对NUMERIC类型的格式化输出逻辑差异:
- PostgreSQL在NUMERIC值为整数时,会自动省略尾部的
.0,只显示整数部分; - DuckDB的NUMERIC类型默认会显示完整的小数部分(即使小数位为0),但数据的实际存储是正确的,只是显示形式不同,数值本身没有变化。
解决办法
1. 查询时格式化输出
使用TO_CHAR函数自定义输出格式,去掉不必要的小数部分:
SELECT col1, TO_CHAR(col2, 'FM999999999') AS col2 FROM public.temp;
FM前缀用于去除格式中的多余空格和尾部的.0,输出结果会显示为:
col1,col2 10,20 11,21
2. 调整表字段类型为INTEGER
如果col2的业务数据本身就是整数,直接将字段类型定义为integer,从根源上避免小数位显示:
CREATE TABLE IF NOT EXISTS public.temp(col1 integer, col2 integer);
3. 定义NUMERIC时指定精度和标度
在创建表时为NUMERIC指定标度为0(即无小数位),这样DuckDB会以整数形式存储和显示:
CREATE TABLE IF NOT EXISTS public.temp(col1 integer, col2 NUMERIC(10, 0));
标度设为0后,加载整数数据时不会显示.0,同时保留NUMERIC类型的高精度特性(如果后续需要存储大整数)。
内容的提问来源于stack exchange,提问作者Vikas Garud
相关产品推荐
相关产品推荐

