DuckDB数据分析实战:读写Excel文件

在企业数据分析场景中,Excel 几乎无处不在。为此,DuckDB 提供了专门的插件,让数据分析师和开发人员可以像查询数据库表一样直接查询 Excel 文件,同时支持将分析结果直接导出为 Excel 文件。

安装插件

DuckDB 官方提供的 Excel 插件(excel)在第一次使用时可以自动安装并加载,也可以手动执行以下命令:

sql 复制代码
INSTALL excel;
LOAD excel;

然后我们准备一个 Excel 示例文件(fruits.xlsx),内容如下:

excel 插件支持 .xlsx 格式文件,但不支持 .xls 格式文件。

读取Excel

DuckDB 可以将 Excel 文件当作一个数据源进行查询,例如:

sql 复制代码
SELECT *
FROM 'fruits.xlsx';

┌─────────┬────────┬────────┐
│  name   │ price  │  num   │
│ varchar │ double │ double │
├─────────┼────────┼────────┤
│ 苹果    │    9.9 │   20.0 │
│ 西瓜    │    2.5 │   15.0 │
│ 梨      │    6.6 │    6.0 │
└─────────┴────────┴────────┘

DuckDB 能够基于文件后缀调用相应的处理函数,对于 XLSX 文件实际调用的是 read_xlsx 函数。因此,以上查询也可以写成下面的语句:

sql 复制代码
SELECT *
FROM read_xlsx('fruits.xlsx', header = true);

其中,header = true 表示读取的内容中包含标题(第一行数据)。

read_xlsx 函数的完整参数如下:

参数 类型 默认值 描述
header BOOLEAN 自动推断 是否将第一行当作标题行。
sheet VARCHAR 自动推断 要读取的 sheet 名称。默认读取第一个 sheet。
all_varchar BOOLEAN false 是否将所有单元格当作 VARCHAR 类型读取。
ignore_errors BOOLEAN false 是否忽略错误并且将无法进行类型转换的数据使用 NULL 替代。
range VARCHAR 自动推断 读取的单元格区域。例如,A1:B2表示读取从 A1 到 B2 之间的单元格。如果没有指定该参数,从第一行连续非空单元格开始向下查找,直到遇到第一个空行;列范围由该数据区域决定。
stop_at_empty BOOLEAN 自动推断 遇到空行时是否停止读取。如果指定了range,该参数默认为false,否则默认为true
empty_as_varchar BOOLEAN false 自动推断类型时,是否将空单元格当作VARCHAR而不是DOUBLE

例如,以下查询只读取了 fruits.xlsx 文件中的第 2 行数据:

sql 复制代码
SELECT *
FROM read_xlsx('fruits.xlsx', range='A2:C2');

┌─────────┬────────┬────────┐
│    A    │   B    │   C    │
│ varchar │ double │ double │
├─────────┼────────┼────────┤
│ 苹果    │    9.9 │   20.0 │
└─────────┴────────┴────────┘

DuckDB 自动推断出数据中没有标题行,因此生成了默认的标题。

另外,导入 Excel 文件时,DuckDB 会基于单元格内容以及/或者格式自动推断列的类型。主要规则包括:

  • 包含日期格式的数据推断为 DATE;
  • 包含时间格式的数据推断为 TIME;
  • 包含时间戳格式的数据推断为 TIMESTAMP;
  • 包含文本 TRUE/FALSE的数据推断为 BOOLEAN;
  • 空单元格默认推断为 DOUBLE,除非使用 empty_as_varchar 参数进行指定;
  • 数值列推断为 DOUBLE;
  • 文本列推断为 VARCHAR。

导入数据

如果需要在 DuckDB 中存储数据,可以将读取的 Excel 内容写入表中。

第一种方法是使用 CREATE TABLE ... AS 语句创建一个新表,例如:

sql 复制代码
CREATE TABLE fruits AS
SELECT *
FROM read_xlsx('fruits.xlsx');

SELECT *
FROM fruits;

┌─────────┬────────┬────────┐
│  name   │ price  │  num   │
│ varchar │ double │ double │
├─────────┼────────┼────────┤
│ 苹果    │    9.9 │   20.0 │
│ 西瓜    │    2.5 │   15.0 │
│ 梨      │    6.6 │    6.0 │
└─────────┴────────┴────────┘

第二种方法是使用 INSERT INTO 语句将数据导入已有的表,例如:

sql 复制代码
CREATE TABLE fruits2(name VARCHAR, price VARCHAR, cnt DOUBLE);

INSERT INTO fruits2
SELECT *
FROM read_xlsx('fruits.xlsx');

SELECT * FROM fruits2;

┌─────────┬─────────┬────────┐
│  name   │  price  │  cnt   │
│ varchar │ varchar │ double │
├─────────┼─────────┼────────┤
│ 苹果    │ 9.9     │   20.0 │
│ 西瓜    │ 2.5     │   15.0 │
│ 梨      │ 6.6     │    6.0 │
└─────────┴─────────┴────────┘

需要注意,fruits2 的字段类型和 Excel 文件不完全相同,此时 DuckDB 会按照目标表字段类型进行转换。

还有一种导入 Excel 文件的方法是使用 COPY 语句,例如:

sql 复制代码
COPY fruits2 FROM 'fruits.xlsx' (FORMAT xlsx, HEADER);

导出Excel

COPY 语句支持将数据表或者查询结果导出为 Excel 文件(.xlsx),例如:

sql 复制代码
COPY employee TO 'employee.xlsx' (FORMAT xlsx, HEADER true);

以上示例将 employee 中的数据写入名为 employee.xlsx 的文件,写入的第一行为标题。

COPY 导出数据时,还可以指定生成的工作表(sheet)名称。例如:

sql 复制代码
COPY (SELECT * FROM employee WHERE dept_id=5)
TO 'employee.xlsx' (FORMAT xlsx, HEADER true, SHEET 'sales');

由于 Excel 底层只支持数字和字符串两种类型,DuckDB 导出到 Excel 文件时会自动执行类型转换:

  • 数字类型转换为 DOUBLE;
  • 时间类型(TIMESTAMP、DATE、TIME)转化为 Excel 序列号数字,并且赋予对应的显示格式;
  • TIMESTAMP_TZ 以及 TIME_TZ 转换为 UTC 时间并且丢失时区信息;
  • BOOLEAN 类型转化为 1 或者 0,并且设置显示为 TRUE 或者 FALSE 的特殊格式;
  • 其他类型转化为文本格式。

最后,我们看一个结合 Excel 导入与导出的示例。假设每个月的销售数据分别存储在一个 Excel 文件中,名称为 sales_202601.xlsx、sales_202602.xlsx、sales_202603.xlsx 等。

以下语句可以完成联合读取多个文件、执行数据分析、写入结果文件的多个操作:

sql 复制代码
COPY ( -- 导出结果文件
    WITH sales AS ( -- 联合读取文件
        SELECT * FROM 'sales_202601.xlsx'
        UNION ALL
        SELECT * FROM 'sales_202602.xlsx'
        UNION ALL
        SELECT * FROM 'sales_202603.xlsx'
    )
    SELECT region, SUM(amount) -- 执行数据分析
    FROM sales
    GROUP BY region
)
TO 'region_sales.xlsx' (FORMAT xlsx, HEADER true);

其中,WITH 相当于定义了一个临时表 sales,包含了多个月份的销售数据;然后基于 sales 进行数据分析;COPY 语句用于导出结果。

相关推荐
正在走向自律21 小时前
时序大模型 TimechoAI 实战指南,让时序数据分析从“手工建模“走向“智能预测“
数据挖掘·数据分析·timechodb·时序数据·时序大模型·timechoai
躺柒1 天前
读数据可视化05视觉感知
信息可视化·数据挖掘·数据分析·视觉·视觉感知
lengjingzju1 天前
一天掌握Vim,精华使用笔记
笔记·vim·excel
cc5725026531 天前
计算机专业考证和做项目哪个重要
数据分析
数模竞赛Paid answer2 天前
2026年电工杯数学建模B题嵌入式社区养老服务站的建设与优化问题求解全过程论文及程序
数学建模·数据分析·电工杯
databook2 天前
如何对稀疏数据的场景进行分析
python·数据挖掘·数据分析
wang_yb2 天前
如何对稀疏数据的场景进行分析
数据分析·databook
灵析表格2 天前
灵析表格财务函数深度实用性分析与实操教程
开发语言·ai·json·excel·wps
科技每日热闻2 天前
AI 赋能财务资金管理、风险预警、经营数据分析,合适的云上财务智能 Agent 有哪些?—— 优先采用 Amazon Quick 四链路解决方案
人工智能·ai·数据挖掘·数据分析