使用 DuckDB 分析 Parquet 文件

上周朋友发我一个小餐馆的订单文件:restaurant_orders.parquet

他说是外卖平台导出的,想看看总共多少单、赚了多少钱、哪个菜卖得好、大家怎么付款。

文件几百 MB,不算大,但也不想为了看几个数去折腾数据库。

我直接用了 DuckDB,它有几个好处:

  • 不用建表,不用导入,直接 read_parquet()
  • SQL 支持完整
  • 窗口函数也有
  • 单机跑,装完就能用

下面按我实际查询的顺序来。

1. 安装 DuckDB,打开文件

安装 DuckDB

curl https://install.duckdb.org | sh
/home/user/.duckdb/cli/latest/duckdb

进去之后先预览前 5 行:

SELECT * FROM read_parquet('/path/to/restaurant_orders.parquet') LIMIT 5;

这里 DuckDB 的优势已经出来了:我连 CREATE TABLE 都没写,直接查 Parquet。

2. 看数据结构

数据已经呈现在眼前,但先别急着动手。

就像做菜前要先认识食材一样,我们得先搞清楚这份数据的“脾气秉性”。

DESCRIBE SELECT * FROM read_parquet('/path/to/restaurant_orders.parquet') LIMIT 5;

输出会告诉你每列类型。比如:

  • order_id:订单号
  • order_time:下单时间
  • customer_name:客户名
  • menu_item:菜品
  • quantity:数量
  • price:单价
  • payment_method:支付方式

先看类型,后面算钱才不会出错。

3. 基础分析:回答朋友的问题

好了,现在我们对数据已经了如指掌,是时候来回答朋友最关心的那几个问题了。

3.1 总共多少单

这是最直接的问题,我们先用一个简单的计数来摸清底数。

SELECT COUNT(*) AS total_orders
FROM read_parquet('/path/to/restaurant_orders.parquet');

3.2 总共卖了多少钱

光知道订单数还不够,朋友最关心的还是赚了多少钱。这里有个小细节,收入是单价乘以数量,可别算错了。

SELECT SUM(price * quantity) AS total_revenue
FROM read_parquet('/path/to/restaurant_orders.parquet');

注意是 price * quantity,不是只加 price

3.3 哪个菜最受欢迎

知道了总收入,朋友又问:“哪个菜卖得最好?我好知道下次备货该重点进什么。”

这个问题,用分组和排序就能轻松搞定。

SELECT menu_item, SUM(quantity) AS total_quantity
FROM read_parquet('/path/to/restaurant_orders.parquet')
GROUP BY menu_item
ORDER BY total_quantity DESC
LIMIT 5;

这里看的是销量。朋友说想知道备货重点,这个结果比销售额更直接。

3.4 大家喜欢怎么付钱

最后一个基础问题,是关于支付方式的。了解顾客的付款习惯,对餐馆的日常运营也很有帮助。

SELECT payment_method, COUNT(*) AS order_count
FROM read_parquet('/path/to/restaurant_orders.parquet')
GROUP BY payment_method
ORDER BY order_count DESC;

微信、支付宝、现金、银行卡,一眼就能看出哪种多。

4. 窗口函数:看趋势和排名

基础问题回答完了,但数据分析的乐趣远不止于此。

DuckDB 对 SQL 标准的支持非常完整,比如强大的窗口函数,能帮我们挖掘出更深层次的信息。

4.1 收入随时间累计

朋友看着总收入,突然好奇:“这一天里,我们的收入是怎么一步步涨上去的?”

这时候,窗口函数就派上用场了,它可以帮我们计算一个“累计和”。

SELECT order_time,
       SUM(price * quantity) OVER (ORDER BY order_time) AS running_revenue
FROM read_parquet('/path/to/restaurant_orders.parquet');

不用自连接,也不用写子查询。直接看一天里收入怎么累计。

4.2 最贵的订单排名

最后,朋友八卦心起,想看看谁是今天的“消费冠军”。

我们可以给所有订单按金额排个名。

SELECT order_id,
       customer_name,
       price * quantity AS order_value,
       RANK() OVER (ORDER BY price * quantity DESC) AS rank
FROM read_parquet('/path/to/restaurant_orders.parquet')
LIMIT 5;

朋友可以拿这个看看大单是谁下的。当然,实际用的时候可以去掉 LIMIT 或者加条件。

5. 总结

这整套流程,我没建数据库,没导数据,没起服务。

DuckDB 直接读 Parquet,用 SQL 把问题一个个查出来。

它适合这种场景:

  • 手头有 Parquet 文件,想快速看数;
  • 不想为了几个查询上 Spark 或建数仓;
  • 需要 SQL 聚合、分组、窗口函数;
  • 本地跑,快,零运维。

如果你也经常拿到 Parquet 文件不知道怎么看,先装个 DuckDB,然后用read_parquet() 读取它,之后就可以使用 SQL 来分析其中的数据了。

文中用到的 parquet 数据文件:restaurant_orders.parquet: https://url11.ctfile.com/f/45455611-17569897503588-39e921?p=6872 (访问密码: 6872)

posted @ 2026-09-20 11:59  wang_yb  阅读(28)  评论(2)    收藏  举报