用 DuckDB 做电商日报:3 个 SQL 查询搞定传统 BI 工具一周的活
每天做电商数据报表?别再用 Tableau 和 Excel 手动拉数据了。本文将带你用 DuckDB 的 3 个核心查询,自动化完成电商日报的全套分析——销售总览、品类深度分析、城市热力图、复购率统计,全部一条 SQL 搞定。
你是否厌倦了每天花 2 小时手动整理电商数据?想要像资深数据工程师一样,仅用几条 SQL 就生成完整的销售日报?本文将带你深入探索 DuckDB 在电商数据分析中的强大能力!从实时销售总览到品类深度分析,从城市热力图到复购率统计,每个知识点都配有实战代码示例。无论你是数据分析师、电商运营还是后端工程师,这些技巧都将大幅提升你的数据分析效率!
你可能有过这样的经历:每天早晨打开电脑,首要任务就是打开 Excel,手动从数据库导出昨天的销售数据,再用透视表做分类汇总,再发结果给老板。光是准备数据就花了一个小时,分析只用了十分钟。而 DuckDB 的做法完全不同:你只需要在现有的数据分析管道里加几条 SQL,日报就自动生成了。没有额外的服务器,没有额外的运维成本,数据就在你的数据库里,查出来直接就能用。
这篇文章的目标很明确:让你在同一个地方完成所有电商数据分析任务。从实时销售总览到品类深度分析,从城市热力图到复购率统计,全部用 SQL 搞定。
一、项目架构:3 个文件搞定整套系统
传统的电商数据报表系统需要搭建 BI 工具、配置数据管道、编写复杂的 ETL 脚本。而 DuckDB 的做法完全不同——它只需要三个文件:
# 1. schema.py — 定义数据表结构
import duckdb
def create_schema(conn):
# 创建电商数据表结构
conn.execute("""
CREATE TABLE IF NOT EXISTS orders (
order_id BIGINT,
customer_id BIGINT,
product_id BIGINT,
quantity INTEGER,
price DECIMAL(10, 2),
order_date DATE,
city VARCHAR,
category VARCHAR
)
""")
# 2. queries.py — 核心查询逻辑
import duckdb
def get_daily_sales_summary(conn):
# 实时销售总览查询
return conn.execute("""
SELECT
DATE(order_date) as sale_date,
COUNT(*) as total_orders,
SUM(price * quantity) as total_revenue,
AVG(price * quantity) as avg_order_value
FROM orders
GROUP BY DATE(order_date)
ORDER BY sale_date DESC
""").fetchdf()
# 3. main.py — 主程序入口
import duckdb
from schema import create_schema
from queries import get_daily_sales_summary
# 创建数据库连接
conn = duckdb.connect('ecommerce.db')
create_schema(conn)
# 执行查询并输出结果
df = get_daily_sales_summary(conn)
print(df.to_string(index=False))
这三个文件构成了完整的电商日报系统。不需要搭建 BI 工具,不需要配置数据管道,只需要一个 DuckDB 数据库连接和几条 SQL 查询。
二、核心查询 1:实时销售总览与传统工具对比
电商日报的首要步骤是获取实时销售总览。传统方案通常需要编写复杂的 SQL 查询,然后手动整理数据。而 DuckDB 只需要一条查询语句:
-- 实时销售总览查询
SELECT
DATE(order_date) as sale_date,
COUNT(*) as total_orders,
SUM(price * quantity) as total_revenue,
AVG(price * quantity) as avg_order_value,
COUNT(DISTINCT customer_id) as unique_customers
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '7 days'
GROUP BY DATE(order_date)
ORDER BY sale_date DESC;
这个查询返回过去 7 天的销售数据,包括订单总数、总销售额、平均订单价值和独立客户数。与传统工具相比,DuckDB 的优势在于:
- 无需部署服务器:DuckDB 是嵌入式数据库,直接在 Python 进程中运行
- 查询速度极快:列式存储 + SIMD 优化,比传统关系型数据库快 10 倍以上
- 代码简洁:一条 SQL 搞定,无需编写复杂的 ETL 脚本
三、核心查询 2:品类深度分析
电商运营需要了解各个品类的销售表现。传统方案需要编写多条查询语句,然后在 Excel 中手动汇总。而 DuckDB 只需要一条查询:
-- 品类深度分析查询
SELECT
category,
COUNT(*) as product_count,
SUM(price * quantity) as category_revenue,
SUM(price * quantity) * 100.0 / (SELECT SUM(price * quantity) FROM orders) as revenue_percentage,
AVG(price * quantity) as avg_order_value
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY category
ORDER BY category_revenue DESC;
这个查询返回各个品类的销售数据,包括商品数量、品类销售额、销售占比和平均订单价值。与传统工具相比,DuckDB 的优势在于:
- 子查询支持:直接在同一查询中计算销售占比,无需编写额外的聚合逻辑
- 实时计算:数据量在百万级时仍能保持毫秒级响应
- 易于扩展:只需要修改 WHERE 条件就可以切换时间范围
四、核心查询 3:城市热力图
城市级别的销售分析对于电商运营非常重要。传统方案需要导入地理信息系统或使用专门的 BI 工具。而 DuckDB 只需要一条查询:
-- 城市级别销售分析查询
SELECT
city,
COUNT(*) as city_orders,
SUM(price * quantity) as city_revenue,
COUNT(DISTINCT customer_id) as city_customers,
PERCENT_RANK() OVER (ORDER BY SUM(price * quantity)) as revenue_rank
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '7 days'
GROUP BY city
ORDER BY city_revenue DESC;
这个查询返回各个城市的销售数据,包括订单数、销售额、客户数和销售排名。与传统工具相比,DuckDB 的优势在于:
- 窗口函数支持:使用 PERCENT_RANK() 直接计算销售排名,无需编写额外的排名逻辑
- 内存高效:城市数据量在万级时仍能保持毫秒级响应
- 易于可视化:查询结果可以直接用于生成热力图
五、核心查询 4:复购率分析
复购率是电商运营的核心指标之一。传统方案需要编写复杂的 SQL 查询来计算复购率。而 DuckDB 只需要一条查询:
-- 复购率分析查询
WITH customer_orders AS (
SELECT
customer_id,
COUNT(*) as order_count,
MIN(order_date) as first_order_date
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '90 days'
GROUP BY customer_id
)
SELECT
COUNT(*) as total_customers,
SUM(CASE WHEN order_count > 1 THEN 1 ELSE 0 END) as repeat_customers,
SUM(CASE WHEN order_count > 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*) as repeat_rate
FROM customer_orders;
这个查询返回过去 90 天的复购率数据,包括总客户数、复购客户数和复购率。与传统工具相比,DuckDB 的优势在于:
- CTE 支持:使用 WITH 语句构建复杂的分析逻辑,代码更易读
- 条件聚合:使用 SUM(CASE WHEN ...) 直接计算复购率,无需编写额外的计算逻辑
- 易于维护:查询逻辑清晰,易于理解和维护
六、性能优化建议
对于大规模电商数据,DuckDB 的性能优化建议如下:
- 使用 Parquet 格式存储数据:Parquet 是列式存储格式,查询速度比 CSV 快 10 倍以上
- 创建索引:对于频繁查询的字段,创建索引可以显著提升查询速度
- 使用分区表:对于时间序列数据,使用分区表可以提高查询效率
# 使用 Parquet 格式存储数据
conn.execute("""
COPY orders TO 'orders.parquet' (FORMAT PARQUET);
""")
# 从 Parquet 文件读取数据
df = conn.execute("SELECT * FROM 'orders.parquet'").fetchdf()
七、生态集成
DuckDB 与 Python 生态的完美集成,使得电商数据分析变得更加简单:
import duckdb
import pandas as pd
# 创建 DuckDB 连接
conn = duckdb.connect('ecommerce.db')
# 执行查询并获取 Pandas DataFrame
df = conn.execute("SELECT * FROM orders").fetchdf()
# 使用 Pandas 进行进一步分析
daily_sales = df.groupby('order_date').agg({
'price': 'sum',
'quantity': 'sum'
}).reset_index()
# 使用 Matplotlib 生成可视化图表
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 6))
plt.plot(daily_sales['order_date'], daily_sales['price'], label='Daily Sales')
plt.title('Daily Sales Trend')
plt.xlabel('Date')
plt.ylabel('Sales')
plt.legend()
plt.show()
总结
通过这篇文章,我们展示了 DuckDB 在电商数据分析中的强大能力。从实时销售总览到品类深度分析,从城市热力图到复购率统计,DuckDB 都用简洁的 SQL 查询完成了传统 BI 工具需要一周才能完成的工作。
DuckDB 的优势在于:
- 无需部署服务器:嵌入式数据库,直接在 Python 进程中运行
- 查询速度极快:列式存储 + SIMD 优化,比传统关系型数据库快 10 倍以上
- 代码简洁:一条 SQL 搞定,无需编写复杂的 ETL 脚本
- 易于扩展:只需要修改查询条件就可以切换分析维度
如果你还在用 Excel 或 Tableau 做电商数据分析,不妨试试 DuckDB。你一定会被它的速度和简洁性所震撼!