◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。
花开月下机器人 使用 DuckDB 分析 Parquet 文件
- 花开月下机器人
- 时间:2026-09-21 15:16:26
- 3人已阅读
---
使用 DuckDB 分析 Parquet 文件
2026 年 9 月 20 日 | 作者:wang_yb
---
场景
朋友发来一个小餐馆的订单文件:restaurant_orders.parquet。他说是外卖平台导出的,想看看总共多少单、赚了多少钱、哪个菜卖得好、大家怎么付款。文件几百 MB,不算大,但也不想为了看几个数去折腾数据库。[citation:58.1][citation:58.47]
DuckDB 恰好是最适合这个场景的工具——不用建表,不用导入,直接 read_parquet()。 SQL 支持完整,窗口函数也有,单机跑,装完就能用。
---
一、安装 DuckDB
curl https://install.duckdb.org | sh
一条命令装好 CLI,进去就能跑 SQL。
---
二、预览数据
SELECT * FROM readparquet('/path/to/restaurantorders.parquet') LIMIT 5;
DuckDB 的优势在这里已经体现出来了:连 CREATE TABLE 都没写,直接查 Parquet 文件。 [citation:58.47]
---
三、了解数据结构
数据在眼前了,但先别急着动手。先看清每一列的类型:
DESCRIBE SELECT * FROM readparquet('/path/to/restaurantorders.parquet');
输出会告诉你每列的名称和类型:
| 列名 | 类型 | 说明 |
|:----|:----|:------|
| order_id | INTEGER | 订单号 |
| order_time | TIMESTAMP | 下单时间 |
| customer_name | VARCHAR | 客户名 |
| menu_item | VARCHAR | 菜品 |
| quantity | INTEGER | 数量 |
| price | DECIMAL | 单价 |
| payment_method | VARCHAR | 支付方式 |
先看类型,后面算钱才不会出错。[citation:58.47]
---
四、基础统计
总共多少单?
SELECT COUNT(*) AS total_orders
FROM readparquet('/path/to/restaurantorders.parquet');
总收入是多少?
这里有个小细节:收入是 单价 × 数量,不是只加单价。
SELECT SUM(price * quantity) AS total_revenue
FROM readparquet('/path/to/restaurantorders.parquet');
---
五、聚合分析
哪个菜卖得最好?
按销量排,比按销售额排更能指导备货:
SELECT menuitem, SUM(quantity) AS totalquantity
FROM readparquet('/path/to/restaurantorders.parquet')
GROUP BY menu_item
ORDER BY total_quantity DESC
LIMIT 5;
支付方式分布
了解顾客的付款习惯,对日常运营也有帮助:
SELECT paymentmethod, COUNT(*) AS ordercount
FROM readparquet('/path/to/restaurantorders.parquet')
GROUP BY payment_method
ORDER BY order_count DESC;
微信、支付宝、现金、银行卡,一眼就能看出哪种多。[citation:58.47]
---
六、窗口函数进阶
DuckDB 对 SQL 标准的支持非常完整,包括窗口函数。
累积收入
朋友看着总收入,想知道一天里收入是怎么一步步涨上去的:
SELECT order_time,
SUM(price * quantity) OVER (ORDER BY ordertime) AS runningrevenue
FROM readparquet('/path/to/restaurantorders.parquet');
不用自连接,也不用写子查询。 直接看一天里收入怎么累计。[citation:58.47]
按金额排名
谁是大单客户?
SELECT orderid, customername,
price * quantity AS order_value,
RANK() OVER (ORDER BY price * quantity DESC) AS rank
FROM readparquet('/path/to/restaurantorders.parquet')
LIMIT 5;
---
七、Python 集成
如果要在 Python 脚本中使用 DuckDB 分析 Parquet 文件:
import duckdb
直接查询 Parquet 文件
result = duckdb.sql("""
SELECT
menu_item,
SUM(quantity) AS total_quantity,
SUM(price * quantity) AS revenue
FROM 'restaurant_orders.parquet'
GROUP BY menu_item
ORDER BY revenue DESC
LIMIT 10
""").df() # 转成 pandas DataFrame
print(result)
与 pandas DataFrame 互通
import pandas as pd
duckdb → pandas
df = duckdb.sql("SELECT * FROM 'orders.parquet'").df()
pandas → duckdb(零拷贝)
duckdb.sql("SELECT payment_method, COUNT(*) FROM df GROUP BY 1")
---
八、导出结果
-- 查询结果导出为 Parquet
COPY (
SELECT menu_item, SUM(quantity) AS qty
FROM read_parquet('/path/to/orders.parquet')
GROUP BY menu_item
) TO 'summary.parquet' (FORMAT PARQUET);
-- 也可以导出为 CSV
COPY (
SELECT * FROM read_parquet('/path/to/orders.parquet')
WHERE payment_method = '微信'
) TO 'wechat_orders.csv' (FORMAT CSV, HEADER);
---
九、适用场景
这套流程最适合以下场景:[citation:58.47]
| 场景 | 说明 |
|:----|:------|
| 手头有 Parquet 文件想快速看数 | 不用建表、不用导入 |
| 不想为了几个查询上 Spark 或建数仓 | 零运维,本地跑 |
| 需要 SQL 聚合、分组、窗口函数 | DuckDB 完整支持 |
| 数据科学工作流 | 与 pandas / Polars 无缝集成 |
| CI 中验证数据管道输出 | 进程内,不需要数据库服务 |
---
十、一句话总结
DuckDB + Parquet 的组合,让你在拿到一个几百 MB 的 Parquet 文件时,不需要导入数据库、不需要启动 Spark、不需要写 Python 脚本做逐行处理——装好 DuckDB,直接 read_parquet(),然后写 SQL 就行了。 从安装到跑出第一个分析结果,大概只需要两分钟。[citation:58.47]