Parquet 是一种强大的、基于列的存储格式,适用于实现更快捷和更高效的数据分析。您可以使用 DuckDB 这种内存型分析数据库来处理 Parquet 文件并运行查询以对其进行分析。···
在这篇文章中,我们将逐步介绍如何使用 DuckDB 对存储在 Parquet 文件中的餐厅订单数据集进行分析。
安装 DuckDB 并开始使用
首先,如果您尚未安装 DuckDB,请执行以下操作:
$ curl https://install.duckdb.org | sh
现在,在您的终端中打开并启动 DuckDB。请务必使用您机器上的正确路径,并将 user 替换为您正确的用户名:
$ /home/user/.duckdb/cli/latest/duckdb
如果需要帮助,请查看安装指南。
▶️获取parquet文件:restaurant_orders.parquet
预览 restaurant_orders.parquet的前5行数据, 执行:
SELECT * FROM read_parquet('restaurant_orders.parquet') LIMIT 5;
输出结果大致如下:
┌──────────┬───────────────┬───┬─────────────────────┬────────────────┐
│ order_id │ customer_name │ … │ order_time │ payment_method │
│ int64 │ varchar │ │ varchar │ varchar │
├──────────┼───────────────┼───┼─────────────────────┼────────────────┤
│ 1 │ Grace │ … │ 2024-02-01 18:00:00 │ PayPal │
│ 2 │ David │ … │ 2024-02-01 18:05:00 │ Credit Card │
│ 3 │ Eve │ … │ 2024-02-01 18:10:00 │ PayPal │
│ 4 │ Grace │ … │ 2024-02-01 18:15:00 │ PayPal │
│ 5 │ Charlie │ … │ 2024-02-01 18:20:00 │ Debit Card │
├──────────┴───────────────┴───┴─────────────────────┴────────────────┤
│ 5 rows 8 columns (4 shown) │
└─────────────────────────────────────────────────────────────────────┘
理解数据集结构
为了理解数据集的模式,我们可以运行:
DESCRIBE SELECT * FROM read_parquet('restaurant_orders.parquet') LIMIT 5;
这将显示每个列的数据类型及其他信息。
┌────────────────┬─────────────┬─────────┬─────────┬─────────┬─────────┐
│ column_name │ column_type │ null │ key │ default │ extra │
│ varchar │ varchar │ varchar │ varchar │ varchar │ varchar │
├────────────────┼─────────────┼─────────┼─────────┼─────────┼─────────┤
│ order_id │ BIGINT │ YES │ NULL │ NULL │ NULL │
│ customer_name │ VARCHAR │ YES │ NULL │ NULL │ NULL │
│ table_number │ BIGINT │ YES │ NULL │ NULL │ NULL │
│ menu_item │ VARCHAR │ YES │ NULL │ NULL │ NULL │
│ price │ DOUBLE │ YES │ NULL │ NULL │ NULL │
│ quantity │ BIGINT │ YES │ NULL │ NULL │ NULL │
│ order_time │ VARCHAR │ YES │ NULL │ NULL │ NULL │
│ payment_method │ VARCHAR │ YES │ NULL │ NULL │ NULL │
└────────────────┴─────────────┴─────────┴─────────┴─────────┴─────────┘
执行基本分析
现在让我们开始分析数据。
- 统计订单总数
让我们来看看数据集中有多少订单:
SELECT COUNT(*) AS total_orders FROM read_parquet('restaurant_orders.parquet');
输出结果:
┌──────────────┐
│ total_orders │
│ int64 │
├──────────────┤
│ 30 │
└──────────────┘
- 计算总收入
让我们看看这家餐厅产生了多少收入:
SELECT SUM(price * quantity) AS total_revenue FROM read_parquet('restaurant_orders.parquet');
输出结果:
┌────────────────────┐
│ total_revenue │
│ double │
├────────────────────┤
│ 1770.9800000000005 │
└────────────────────┘
- 查找最受欢迎的菜品
哪些菜品的销量最高呢?让我们按菜品名称(menu_item)进行分组,并汇总数量:
SELECT menu_item, SUM(quantity) AS total_quantity
FROM read_parquet('restaurant_orders.parquet')
GROUP BY menu_item
ORDER BY total_quantity DESC
LIMIT 5;
输出结果:
┌───────────┬────────────────┐
│ menu_item │ total_quantity │
│ varchar │ int128 │
├───────────┼────────────────┤
│ Pizza │ 16 │
│ Sushi │ 15 │
│ Salad │ 14 │
│ Tacos │ 14 │
│ Soup │ 7 │
└───────────┴────────────────┘
- 按支付方式分析销售额
顾客是通过何种方式支付餐费的呢?让我们来一探究竟:
SELECT payment_method, COUNT(*) AS order_count
FROM read_parquet('restaurant_orders.parquet')
GROUP BY payment_method
ORDER BY order_count DESC;
输出:
┌────────────────┬─────────────┐
│ payment_method │ order_count │
│ varchar │ int64 │
├────────────────┼─────────────┤
│ PayPal │ 9 │
│ Credit Card │ 8 │
│ Cash │ 7 │
│ Debit Card │ 6 │
└────────────────┴─────────────┘
高级分析与窗口函数
窗口函数可以帮助计算有趣的信息:
- 一段时间内的总收益
让我们算一下营业收入:
SELECT order_time, SUM(price * quantity) OVER (ORDER BY order_time) AS running_revenue
FROM read_parquet('restaurant_orders.parquet');
从 Parquet 文件中读取餐厅订单数据,并计算随时间累积的营业收入。具体逻辑如下:
- 先对每行计算单笔订单收入:
price * quantity
。 - 通过窗口函数
SUM(...) OVER (ORDER BY order_time)
,按order_time
升序排列,累加所有历史订单收入。
结果:running_revenue
表示从第一条订单到当前行的累计总收入。
核心用途:
- 实时营收监控:观察收入随时间的变化趋势。
- 业务分析:识别高峰时段或促销活动的收入贡献。
- 数据验证:检查订单金额与累计值的逻辑一致性。
扩展性:可结合 PARTITION BY
(如按门店或服务员分组)实现多维度累积分析。
- 最昂贵订单排名
现在我们将找出最昂贵的订单:
SELECT order_id, customer_name, price * quantity AS order_value,RANK() OVER (ORDER BY price * quantity DESC) AS rank
FROM read_parquet('restaurant_orders.parquet')
LIMIT 5;
输出:
┌──────────┬───────────────┬────────────────────┬───────┐
│ order_id │ customer_name │ order_value │ rank │
│ int64 │ varchar │ double │ int64 │
├──────────┼───────────────┼────────────────────┼───────┤
│ 24 │ Hannah │ 175.36 │ 1 │
│ 6 │ Hannah │ 126.87 │ 2 │
│ 17 │ David │ 125.10000000000001 │ 3 │
│ 14 │ Charlie │ 119.25 │ 4 │
│ 20 │ Charlie │ 119.13 │ 5 │
└──────────┴───────────────┴────────────────────┴───────┘
总结:
DuckDB使处理Parquet文件变得高效——允许我们快速分析结构化数据。