• 使用 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)

  • 相关阅读:
    每日一记 关于Python的准备知识、快速上手
    Mybatis 的架构原理解读
    使用azure-data factory
    面试又卡在多线程?那就来分享几道 Java 多线程高频面试题,面试不用愁
    ElementUI之CUD+表单验证
    慌了,面试官问我G1垃圾收集器
    pyautogui 记录
    _Linux理解软硬链接
    【python】字典的使用
    ThinkCentre台式机windows重装为linux找不到硬盘
  • 原文地址:https://www.cnblogs.com/wang_yb/p/23046497