Featured image of post DuckDB 电商多平台运营看板:跨店数据聚合实战

DuckDB 电商多平台运营看板:跨店数据聚合实战

用 DuckDB 聚合淘宝、拼多多、京东三平台订单 CSV,10 行 SQL 搞定跨平台对比分析,输出 6 维度 Excel 报表 + Plotly 交互式 HTML 看板。一个完整项目报价 ¥2000-5000,复制即可交付。

问题:多平台卖家的数据噩梦

开淘宝店的,往往也开了拼多多和京东。每天打开三个后台 → 分别导出 CSV → 粘贴进 Excel → 手动做对比 → 整理成老板要看的样子。这个过程每天至少 1 小时,月底汇总更是噩梦。

这是电商运营最真实的痛点。不算那些百万级大卖家——他们有 BI 团队。真正痛苦的是月销 10-200 万的腰部卖家,几百个 SKU,三四个平台,数据全在 CSV 里。

他们面临的三个核心问题:

  1. 数据分散 — 每个平台有自己的导出格式,字段名不一样(淘宝叫"实收金额",拼多多叫"商家实收"),没法直接对比
  2. 手工聚合慢 — Excel 手动合并,VLOOKUP 到处飞,容易出错
  3. 没有看板 — 想看一眼各平台实时占比?没有。想看 Top SKU 排名?得手工算半小时

以前怎么?用 Python + Pandas 写脚本——但 Pandas 加载三个月几十万行订单数据,8GB 内存笔记本直接卡死。或者上 BI 工具——Tableau 每人 $70/月,小卖家不舍得。

DuckDB 的方案:一个 .py 文件,零安装数据库,10 行 SQL 搞定全部。

DuckDB 解法:UNION ALL 跨平台聚合

DuckDB 最核心的优势在这里展现得淋漓尽致——它能直接读 CSV,自动推断 schema,然后用 SQL 做跨平台数据清洗和聚合。

三个平台 CSV 的 schema 不一样?没关系,用 UNION ALL BY NAME 自动按列名对齐:

SELECT '淘宝' AS platform, order_id, amount, sku, province, order_date
FROM read_csv_auto('taobao_orders.csv')
UNION ALL BY NAME
SELECT '拼多多' AS platform, order_id, amount, sku, province, order_date
FROM read_csv_auto('pdd_orders.csv')
UNION ALL BY NAME
SELECT '京东' AS platform, order_id, amount, sku, province, order_date
FROM read_csv_auto('jd_orders.csv')

以前这个操作:Pandas 读三个 CSV → 手动统一列名(3-5 行)→ concat()(1 行)→ 类型转换(3-5 行)。数据量到了 50 万行,Pandas 内存占用 2-3GB。

DuckDB 的这个操作:1 行 SQL,零拷贝,零内存浪费。DuckDB 的列式引擎只扫描你需要的列,read_csv_auto 自动处理 schema 差异。

完整代码:从 CSV 到 6 维度看板

下面这个脚本是完整的可交付方案。它会:

  1. 自动生成三个平台的模拟订单数据(你也可以换成真实 CSV 文件)
  2. 用 DuckDB 做 6 个维度的跨平台分析
  3. 输出两个交付物:6-Sheet Excel 报表 + 交互式 HTML 看板

前置条件

pip install duckdb pandas openpyxl plotly numpy

DuckDB 版本要求 1.5+(UNION ALL BY NAME 语法从 v0.10.0 开始支持)。

完整脚本

#!/usr/bin/env python3
"""
DuckDB 电商多平台运营看板
输出:6-Sheet Excel 报表 + Plotly 交互式 HTML 看板
"""

import duckdb
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import random

# ============ 第1步:生成模拟数据(实际使用时替换为真实 CSV 路径)============
print("🔄 生成模拟订单数据...")

def gen_orders(platform, stores, n_days=90):
    """为某个平台生成 n_days 天的订单"""
    skus = [f"{platform[:2]}-{chr(65+i)}-{random.randint(100,999)}" 
            for i in range(random.randint(15, 25))]
    categories = {
        '服装': ['男装', '女装', '童装'],
        '数码': ['手机', '配件', '耳机'],
        '家居': ['厨具', '家纺', '收纳']
    }
    province_pool = ['广东', '浙江', '江苏', '上海', '北京', '四川', '湖北', 
                     '山东', '福建', '河南']
    start_date = datetime.now() - timedelta(days=n_days)
    
    rows = []
    for store in stores:
        for day_offset in range(n_days):
            n_orders = random.randint(5, 30)
            date = start_date + timedelta(days=day_offset)
            for _ in range(n_orders):
                cat = random.choice(list(categories.keys()))
                sub_cat = random.choice(categories[cat])
                sku = random.choice(skus)
                qty = random.randint(1, 5)
                price = random.choice([29.9, 49.9, 79.9, 99, 129, 199, 299, 499])
                rows.append({
                    'order_id': f"{platform[:2]}{date.strftime('%y%m%d')}{random.randint(10000,99999)}",
                    'order_date': date.strftime('%Y-%m-%d'),
                    'store': store,
                    'sku': sku,
                    'category': cat,
                    'sub_category': sub_cat,
                    'quantity': qty,
                    'amount': round(qty * price, 2),
                    'province': random.choice(province_pool),
                    'platform': platform
                })
    return pd.DataFrame(rows)

# 生成数据
taobao_df = gen_orders('淘宝', ['旗舰店', '专营店', '工厂店'])
pdd_df = gen_orders('拼多多', ['官方旗舰店', '品牌店'])
jd_df = gen_orders('京东', ['自营旗舰店', '第三方专营店'])

# 保存为 CSV(模拟从平台导出的情景)
taobao_df.to_csv('taobao_orders.csv', index=False)
pdd_df.to_csv('pdd_orders.csv', index=False)
jd_df.to_csv('jd_orders.csv', index=False)

print(f"  ✅ 淘宝: {len(taobao_df)} 条订单")
print(f"  ✅ 拼多多: {len(pdd_df)} 条订单")
print(f"  ✅ 京东: {len(jd_df)} 条订单")

# ============ 第2步:用 DuckDB 做跨平台聚合分析 ============
print("\n🔄 运行 DuckDB 跨平台分析...")

con = duckdb.connect()

# 2a. KPI 总览
kpi_overview = con.execute("""
    WITH unified AS (
        SELECT * FROM read_csv_auto('taobao_orders.csv')
        UNION ALL BY NAME
        SELECT * FROM read_csv_auto('pdd_orders.csv')
        UNION ALL BY NAME
        SELECT * FROM read_csv_auto('jd_orders.csv')
    )
    SELECT 
        platform,
        COUNT(*) AS 订单数,
        ROUND(SUM(amount), 0) AS 总销售额,
        ROUND(AVG(amount), 2) AS 客单价,
        ROUND(SUM(quantity), 0) AS 总销量,
        ROUND(SUM(amount) / NULLIF(SUM(quantity), 0), 2) AS 件单价,
        COUNT(DISTINCT sku) AS SKU数,
        ROUND(SUM(CASE WHEN province IN ('广东','浙江','江苏') THEN amount ELSE 0 END) 
              / SUM(amount) * 100, 1) AS 核心省份占比_pct
    FROM unified
    GROUP BY platform
    ORDER BY 总销售额 DESC
""").fetchdf()

print("\n📊 各平台 KPI:")
print(kpi_overview.to_string(index=False))

# 2b. 每日销售额趋势
daily_trend = con.execute("""
    WITH unified AS (
        SELECT * FROM read_csv_auto('taobao_orders.csv')
        UNION ALL BY NAME
        SELECT * FROM read_csv_auto('pdd_orders.csv')
        UNION ALL BY NAME
        SELECT * FROM read_csv_auto('jd_orders.csv')
    )
    SELECT order_date, platform, ROUND(SUM(amount), 0) AS sales
    FROM unified
    GROUP BY order_date, platform
    ORDER BY order_date, platform
""").fetchdf()

# 2c. SKU 销售排名
sku_rank = con.execute("""
    WITH unified AS (
        SELECT * FROM read_csv_auto('taobao_orders.csv')
        UNION ALL BY NAME
        SELECT * FROM read_csv_auto('pdd_orders.csv')
        UNION ALL BY NAME
        SELECT * FROM read_csv_auto('jd_orders.csv')
    )
    SELECT 
        sku, category, sub_category,
        ROUND(SUM(amount), 0) AS 总销售额,
        SUM(quantity) AS 总销量,
        ROUND(AVG(amount / quantity), 2) AS 均价,
        COUNT(DISTINCT platform) AS 覆盖平台数
    FROM unified
    GROUP BY sku, category, sub_category
    ORDER BY 总销售额 DESC
    LIMIT 20
""").fetchdf()

# 2d. 品类分析
cat_analysis = con.execute("""
    WITH unified AS (
        SELECT * FROM read_csv_auto('taobao_orders.csv')
        UNION ALL BY NAME
        SELECT * FROM read_csv_auto('pdd_orders.csv')
        UNION ALL BY NAME
        SELECT * FROM read_csv_auto('jd_orders.csv')
    )
    SELECT 
        category, platform,
        ROUND(SUM(amount), 0) AS 销售额,
        COUNT(*) AS 订单数,
        ROUND(SUM(amount) / SUM(SUM(amount)) OVER (PARTITION BY category) * 100, 1) AS 平台占比_pct
    FROM unified
    GROUP BY category, platform
    ORDER BY category, 销售额 DESC
""").fetchdf()

# 2e. 各平台热销 Top 3
top3_per_platform = con.execute("""
    WITH unified AS (
        SELECT * FROM read_csv_auto('taobao_orders.csv')
        UNION ALL BY NAME
        SELECT * FROM read_csv_auto('pdd_orders.csv')
        UNION ALL BY NAME
        SELECT * FROM read_csv_auto('jd_orders.csv')
    ),
    sku_sales AS (
        SELECT platform, sku, category,
               ROUND(SUM(amount), 0) AS sales,
               ROW_NUMBER() OVER (PARTITION BY platform ORDER BY SUM(amount) DESC) AS rank
        FROM unified
        GROUP BY platform, sku, category
    )
    SELECT platform, sku, category, sales
    FROM sku_sales
    WHERE rank <= 3
    ORDER BY platform, rank
""").fetchdf()

# 2f. 整体销售趋势(跨平台合计)
overall_trend = con.execute("""
    WITH unified AS (
        SELECT * FROM read_csv_auto('taobao_orders.csv')
        UNION ALL BY NAME
        SELECT * FROM read_csv_auto('pdd_orders.csv')
        UNION ALL BY NAME
        SELECT * FROM read_csv_auto('jd_orders.csv')
    )
    SELECT order_date, ROUND(SUM(amount), 0) AS total_sales
    FROM unified
    GROUP BY order_date
    ORDER BY order_date
""").fetchdf()

con.close()
print("  ✅ DuckDB 分析完成")

# ============ 第3步:输出为 Excel 报表(6个 Sheet)============
print("\n🔄 生成 Excel 报表...")
with pd.ExcelWriter('电商多平台运营报表.xlsx', engine='openpyxl') as writer:
    kpi_overview.to_excel(writer, sheet_name='KPI总览', index=False)
    overall_trend.to_excel(writer, sheet_name='每日销售趋势', index=False)
    sku_rank.to_excel(writer, sheet_name='SKU销售排名', index=False)
    cat_analysis.to_excel(writer, sheet_name='品类分析', index=False)
    top3_per_platform.to_excel(writer, sheet_name='各平台热销Top3', index=False)
    daily_trend.to_excel(writer, sheet_name='每日分平台趋势', index=False)
print("  ✅ 电商多平台运营报表.xlsx 已生成")

# ============ 第4步:输出 Plotly 交互式 HTML 看板 ============
print("\n🔄 生成交互式 HTML 看板...")
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# 看板标题
html = """
<html><head><meta charset="utf-8">
<title>电商多平台运营看板</title>
<style>
body { font-family: -apple-system, BlinkMacSystemFont, sans-serif; margin: 20px; background: #f5f5f5; }
h1 { color: #2c3e50; text-align: center; }
.container { max-width: 1400px; margin: 0 auto; }
.card { background: white; padding: 20px; margin: 15px 0; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
.card h2 { color: #34495e; margin-top: 0; }
.kpi-row { display: flex; gap: 15px; flex-wrap: wrap; }
.kpi-card { flex: 1; min-width: 150px; background: #f8f9fa; padding: 15px; border-radius: 8px; text-align: center; }
.kpi-value { font-size: 24px; font-weight: bold; color: #2c3e50; }
.kpi-label { font-size: 13px; color: #7f8c8d; }
</style></head><body>
<div class="container">
<h1>🦆 电商多平台运营看板</h1>
<p style="text-align:center;color:#7f8c8d;">数据周期:过去90天 | 平台:淘宝 / 拼多多 / 京东</p>
"""

# KPI 卡片
kpi_card_html = '<div class="card"><h2>📊 总体 KPI</h2><div class="kpi-row">'
for _, row in kpi_overview.head(3).iterrows():
    kpi_card_html += f"""
    <div class="kpi-card">
        <div class="kpi-label">{row['platform']}</div>
        <div class="kpi-value">¥{row['总销售额']:,.0f}</div>
        <div style="font-size:12px;color:#95a5a6;">{row['订单数']} 单 | 客单价 ¥{row['客单价']}</div>
    </div>"""
kpi_card_html += '</div></div>'
html += kpi_card_html

# 图1:总销售趋势
fig1 = px.line(overall_trend, x='order_date', y='total_sales',
               title='📈 总销售趋势(跨平台合计)',
               labels={'order_date': '日期', 'total_sales': '销售额 (¥)'})
fig1.update_layout(template='plotly_white', height=400)
html += f'<div class="card">{fig1.to_html(full_html=False, include_plotlyjs="cdn")}</div>'

# 图2:每日各平台趋势
fig2 = px.line(daily_trend, x='order_date', y='sales', color='platform',
               title='📊 各平台每日销售额对比',
               labels={'order_date': '日期', 'sales': '销售额 (¥)', 'platform': '平台'})
fig2.update_layout(template='plotly_white', height=400)
html += f'<div class="card">{fig2.to_html(full_html=False, include_plotlyjs="cdn")}</div>'

# 图3:品类分析 - 气泡图
fig3 = px.sunburst(cat_analysis, path=['category', 'platform'], values='销售额',
                   title='🎯 品类 - 平台 销售额分布',
                   color='销售额', color_continuous_scale='blues')
fig3.update_layout(height=500)
html += f'<div class="card">{fig3.to_html(full_html=False, include_plotlyjs="cdn")}</div>'

# 图4:SKU Top 20
fig4 = px.bar(sku_rank.head(20), x='总销售额', y='sku', color='category',
              orientation='h',
              title='🏆 SKU 销售额 Top 20',
              labels={'总销售额': '销售额 (¥)', 'sku': 'SKU', 'category': '品类'},
              text='总销售额')
fig4.update_layout(template='plotly_white', height=600, yaxis={'categoryorder':'total ascending'})
html += f'<div class="card">{fig4.to_html(full_html=False, include_plotlyjs="cdn")}</div>'

html += """
<div class="card" style="text-align:center;color:#7f8c8d;">
<p>🦆 由 DuckDB 驱动 · 本看板为静态 HTML,数据截至生成时刻</p>
</div></div></body></html>"""

with open('电商多平台运营看板.html', 'w', encoding='utf-8') as f:
    f.write(html)
print("  ✅ 电商多平台运营看板.html 已生成")

print("\n" + "="*50)
print("🎉 交付完成!")
print("  📁 电商多平台运营报表.xlsx (6个Sheet)")
print("  📁 电商多平台运营看板.html (Plotly 交互式看板)")
print("="*50)

运行方法

python day16_shop_dashboard.py

脚本运行后,你会在当前目录看到两个文件:

文件说明
电商多平台运营报表.xlsx6 个 Sheet 的 Excel 报表(KPI总览/每日趋势/SKU排名/品类分析/热销Top3/分平台趋势)
电商多平台运营看板.htmlPlotly 交互式 HTML 看板,在浏览器中打开即可

替换真实数据

把脚本中生成模拟数据的部分替换为读取真实 CSV:

# 替换这段:
taobao_df = gen_orders('淘宝', ...)

# 改为:
taobao_df = pd.read_csv('后台导出的淘宝订单.csv')
pdd_df = pd.read_csv('后台导出的拼多多订单.csv')
jd_df = pd.read_csv('后台导出的京东订单.csv')

脚本会自动适配 CSV 中的列名,UNION ALL BY NAME 会根据列名自动匹配。

与传统方案对比

方案代码量内存占用 (50万行)学习成本成本
Excel 手动合并全靠手点N/A免费但费时
Python + Pandas50-80 行2-3 GB免费
DuckDB 方案~20 行 SQL<200 MB低(会 SQL 就行)免费
Tableau / Power BI零代码(但贵)N/A中高$70/月/人
自研数据中台上万行N/A极高十几万起

变现方案

目标客户

月销 10-200 万的腰部电商卖家,同时经营 2-3 个平台,对数据敏感但不会编程。

报价区间

服务模式报价说明
一次性交付脚本+看板¥2,000-3,000适配客户的数据格式,交付后不再修改
月度维护+数据更新¥500-1,000/月每月更新看板,新增分析维度
定制开发(含更多维度)¥5,000-8,000包含库存预警、利润分析、广告ROI等

交付清单

  • 客户提供:各平台 CSV 导出(至少 3 个月的订单数据)
  • 你交付:适配后的 Python 脚本 + Excel 报表 + HTML 看板
  • 验收标准:各平台销售额总和与客户后台对得上

获客渠道

  1. 闲鱼 — 搜索"电商数据看板"“淘宝数据分析”,看谁在求这个
  2. 小红书 — 发笔记标题如"3 个平台的订单怎么合并?一个脚本搞定"
  3. 电商卖家群/朋友圈 — 直接展示看板截图

扩展思路

  1. 叠加更多的数据源 — 加上广告投放数据(直通车/多多搜索/京东快车),做 ROI 分析,报价可以翻倍
  2. 库存联动 — 对接进销存数据,做缺货预警,这个功能价值极高
  3. 做成 SaaS — 多个客户上传 CSV → DuckDB 后台处理 → 每个客户一个看板链接。年费 ¥999/客户
  4. 行业定制版 — 专门做某个品类(如服装/食品/电子),针对性更强的分析维度

架构图

为什么用 DuckDB 做这个项目

这个项目的本质需求是:把散落在多个 CSV 里的数据,快速聚合、分析、可视化。DuckDB 是最适合这个场景的工具:

  • 零依赖:不需要装数据库,一个 pip install 搞定
  • 自动推断:read_csv_auto 自动适配不同平台的 CSV 格式
  • 列式引擎:只读需要的列,内存占用是 Pandas 的 1/10
  • SQL 标准:会 SQL 就能做数据分析,不需要学 Pandas
  • 输出灵活:可以输出到 Pandas DataFrame(转 Excel),也可以直接用 SQL 做聚合

一句话总结:一个 DuckDB Python 脚本 = 一条完整的数据分析服务产品线。

📺 Watch video tutorials → DuckDB Lab YouTube

Subscribe for more DuckDB & AI automation tutorials

使用 Hugo 构建
主题 StackJimmy 设计