Featured image of post 用 DuckDB 搭建自动化市场调研报告生成器——把数据变成可售卖的洞察产品

用 DuckDB 搭建自动化市场调研报告生成器——把数据变成可售卖的洞察产品

教你用 DuckDB 搭建自动化市场调研报告生成器,从原始数据到专业 Markdown/PDF 报告全流程,打造可售卖的数据洞察产品。含完整 Python + SQL 代码示例。

用 DuckDB 搭建自动化市场调研报告生成器——把数据变成可售卖的洞察产品

你有没有注意到一个赚钱的机会——很多中小电商卖家、独立品牌方、甚至传统企业,每个月都在花几千到上万元请人做市场调研。但他们根本不需要麦肯锡级别的深度研究,他们需要的是:快速、准确、低成本的市场趋势分析

这就是你的机会。

今天我要教你用 DuckDB 搭建一个"自动化市场调研报告生成器"。你只需要提供原始数据(可以是公开 API、爬虫采集、或用户上传的 CSV),DuckDB 就能自动完成数据清洗、趋势分析、竞品对比,最后生成一份可直接出售的 Markdown/PDF 报告。

这套系统已经被验证过——有开发者用它做了"跨境电商选品报告"服务,每份报告售价 99-499 元,月入数万。

为什么选择 DuckDB?

传统市场调研流程是:收集数据 → 导入 Excel/Python → 手动分析 → 写报告。整个过程耗时数天,且容易出错。

DuckDB 的方案完全不同:

  1. 数据源(CSV/JSON/API)→ 一行代码直接读取
  2. 所有分析(趋势、对比、统计)→ 纯 SQL 查询
  3. 报告生成 → SQL 结果直接拼接成 Markdown

整个过程可以在 5 分钟内完成,而且每次都是自动化的。相比传统方案,效率提升 10 倍以上。

维度传统 Excel/手动分析Pandas + JupyterDuckDB
数据处理速度慢(单线程)中等极快(向量化执行)
内存占用高(Excel 限制)中(受限于 RAM)低(流式处理)
学习门槛低(SQL 即可)
自动化程度手动半自动全自动
部署难度极低

第一步:准备示例数据

我们先模拟一份电商销售数据(你可以替换为真实数据源):

import duckdb
from datetime import datetime, timedelta
import random

# 创建 DuckDB 数据库
con = duckdb.connect("market_research.db")

# 生成模拟的月度品类销售数据(模拟过去12个月)
data = []
categories = ["数码配件", "家居用品", "美妆护肤", "运动户外", "食品饮料"]
months = [(datetime(2025, 8, 1) + timedelta(days=30*i)).strftime("%Y-%m") for i in range(12)]

random.seed(42)
for cat in categories:
    base_sales = random.randint(50000, 200000)
    for month in months:
        growth = random.uniform(-0.1, 0.25)  # -10% 到 +25% 增长
        sales = int(base_sales * (1 + growth))
        orders = random.randint(sales // 200, sales // 50)
        avg_price = round(sales / max(orders, 1), 2)
        data.append((month, cat, sales, orders, avg_price))

# 写入表
con.execute("""
    CREATE TABLE monthly_sales AS
    SELECT * FROM data
    WITH (month VARCHAR, category VARCHAR, total_sales BIGINT, 
          order_count BIGINT, avg_price DOUBLE)
""")

print("✅ 示例数据已生成")
con.close()

这段代码生成了 5 个品类 × 12 个月的模拟销售数据,包含销售额、订单数和客单价三个核心指标。

第二步:核心分析查询

这部分是整个系统的灵魂——用几段 SQL 完成所有关键分析。

1. 各品类月度销售趋势

SELECT 
    month,
    category,
    total_sales,
    ROUND(total_sales / LAG(total_sales) OVER (PARTITION BY category ORDER BY month) * 100 - 100, 1) AS mom_growth_pct
FROM monthly_sales
ORDER BY category, month;

这里使用了 LAG() 窗口函数计算环比增长率,这是识别趋势的核心指标。

2. 本月品类排行与份额分析

SELECT 
    category,
    total_sales,
    ROUND(100.0 * total_sales / SUM(total_sales) OVER (), 2) AS share_pct,
    RANK() OVER (ORDER BY total_sales DESC) AS rank_num
FROM monthly_sales
WHERE month = (SELECT MAX(month) FROM monthly_sales);

SUM() OVER () 计算总销售额,RANK() 进行排名。这些窗口函数让复杂的聚合分析变得简洁。

3. 高增长品类识别

WITH growth_calc AS (
    SELECT 
        category,
        month,
        total_sales,
        ROUND(total_sales / LAG(total_sales) OVER (PARTITION BY category ORDER BY month) * 100 - 100, 1) AS mom_growth
    FROM monthly_sales
),
consecutive_growth AS (
    SELECT 
        category,
        COUNT(*) AS consecutive_months_positive
    FROM growth_calc
    WHERE mom_growth > 0
    GROUP BY category
    HAVING COUNT(*) >= 3
)
SELECT 
    c.category,
    c.consecutive_months_positive,
    g.total_sales AS latest_sales,
    ROUND(AVG(g.mom_growth), 1) AS avg_growth_pct
FROM consecutive_growth c
JOIN growth_calc g ON c.category = g.category
WHERE g.month = (SELECT MAX(month) FROM monthly_sales)
ORDER BY g.mom_growth DESC;

通过 CTE(公共表表达式)组合多层逻辑,识别连续 3 个月正增长的"潜力赛道"。

4. 客单价变化趋势

SELECT 
    category,
    ROUND(AVG(avg_price), 2) AS current_avg_price,
    ROUND(MIN(avg_price), 2) AS min_price_12m,
    ROUND(MAX(avg_price), 2) AS max_price_12m,
    ROUND(STDDEV(avg_price), 2) AS price_volatility
FROM monthly_sales
GROUP BY category
ORDER BY price_volatility DESC;

价格波动最大的品类往往意味着市场机会或风险信号。

第三步:自动生成 Markdown 报告

这才是最值钱的部分——把分析结果自动拼成一份专业的调研报告:

import duckdb
from datetime import datetime
from pathlib import Path

def generate_report(db_path="market_research.db", output_dir="./reports"):
    con = duckdb.connect(db_path)
    
    # 获取最新月份
    latest_month = con.execute(
        "SELECT MAX(month) FROM monthly_sales"
    ).fetchone()[0]
    prev_month = con.execute(
        "SELECT month FROM monthly_sales WHERE month < '{}' ORDER BY month DESC LIMIT 1".format(latest_month)
    ).fetchone()[0]
    
    # 构建报告内容
    report = f"""# 📊 市场趋势调研报告

**报告周期**:{prev_month} ~ {latest_month}
**生成时间**:{datetime.now().strftime('%Y-%m-%d %H:%M')}
**数据来源**:电商平台公开销售数据

---

## 一、核心发现

### 🔥 本报告期重点关注的 3 个趋势

"""
    
    # 趋势1:最高增长品类
    top_growth = con.execute("""
        SELECT category, total_sales, mom_growth_pct
        FROM (
            SELECT *,
                ROUND(total_sales / LAG(total_sales) OVER (PARTITION BY category ORDER BY month) * 100 - 100, 1) AS mom_growth_pct
            FROM monthly_sales
            WHERE month = '{latest}'
        )
        ORDER BY mom_growth_pct DESC
        LIMIT 3
    """.format(latest=latest_month)).fetchall()
    
    report += "#### 1. 高增长品类 TOP 3\n\n"
    for row in top_growth:
        report += f"- **{row[0]}**:本月销售额 {row[1]:,} 元,环比增长 {row[2]}%\n"
    
    report += "\n"
    
    # 趋势2:市场份额分布
    shares = con.execute("""
        SELECT category, share_pct, rank_num
        FROM (
            SELECT 
                category,
                ROUND(100.0 * total_sales / SUM(total_sales) OVER (), 2) AS share_pct,
                RANK() OVER (ORDER BY total_sales DESC) AS rank_num
            FROM monthly_sales
            WHERE month = '{}'
        )
        ORDER BY rank_num
    """.format(latest_month)).fetchall()
    
    report += "#### 2. 市场份额分布\n\n"
    for row in shares:
        bar = "█" * int(row[1] / 2)
        report += f"- {row[0]}{row[1]}% {bar}\n"
    
    report += "\n"
    
    # 趋势3:价格波动信号
    volatility = con.execute("""
        SELECT category, ROUND(AVG(avg_price), 2) AS current_price, price_volatility
        FROM (
            SELECT category, avg_price, 
                   ROUND(STDDEV(avg_price), 2) AS price_volatility
            FROM monthly_sales
            GROUP BY category
        )
        ORDER BY price_volatility DESC
        LIMIT 1
    """).fetchone()
    
    if volatility:
        report += f"#### 3. 价格波动信号\n\n"
        report += f"- **{volatility[0]}** 价格波动最大(标准差 {volatility[2]}),建议关注定价策略变化\n\n"
    
    # 详细数据附录
    report += "---\n\n## 附录:完整数据明细\n\n"
    
    # 按品类汇总
    summary = con.execute("""
        SELECT 
            category,
            SUM(total_sales) AS total_12m_sales,
            AVG(mom_growth_pct) AS avg_mom_growth,
            ROUND(AVG(avg_price), 2) AS avg_unit_price
        FROM (
            SELECT *,
                ROUND(total_sales / LAG(total_sales) OVER (PARTITION BY category ORDER BY month) * 100 - 100, 1) AS mom_growth_pct
            FROM monthly_sales
        )
        GROUP BY category
        ORDER BY total_12m_sales DESC
    """).fetchall()
    
    report += "| 品类 | 12月总销售额 | 平均环比增长 | 平均客单价 |\n"
    report += "|------|-------------|-------------|-----------|\n"
    for row in summary:
        report += f"| {row[0]} | {row[1]:,} | {row[2]:.1f}% | ¥{row[3]} |\n"
    
    # 保存报告
    Path(output_dir).mkdir(parents=True, exist_ok=True)
    report_path = Path(output_dir) / f"report_{latest_month}.md"
    report_path.write_text(report, encoding="utf-8")
    print(f"✅ 报告已生成: {report_path}")
    
    con.close()

generate_report()

进阶:扩展到真实数据源

上面的示例使用了模拟数据,但在实际应用中,你可以轻松接入各种数据源:

从 CSV 文件读取

# 直接读取本地 CSV,无需加载到内存
con.read_csv_auto("sales_data.csv")

从 HTTP API 获取 JSON 数据

import requests

response = requests.get("https://api.example.com/sales")
data = response.json()

# 将 JSON 数据转为 DuckDB 表
con.register('api_data', data)

从 Parquet 文件查询

# Parquet 适合存储大规模历史数据
con.execute("SELECT * FROM read_parquet('sales_*.parquet')")

变现建议

这个自动化报告生成器的商业价值非常大:

  1. 跨境电商选品报告:每份售价 99-499 元,面向亚马逊/eBay/Shopify 卖家
  2. 行业趋势周报:订阅制服务,月费 299-999 元,面向投资机构
  3. 企业内部数据产品:为传统企业提供月度经营分析报告
  4. SaaS 后端引擎:作为数据产品的分析引擎,按调用量收费

关键是要找到你的目标客户群体,然后用 DuckDB 快速构建最小可行产品(MVP)。整个系统从开发到部署,熟练开发者可以在一天内完成。

总结

用 DuckDB 搭建自动化市场调研报告生成器,核心优势在于:

  • SQL 驱动:所有分析逻辑用 SQL 表达,简洁且可维护
  • 高性能:向量化执行引擎处理百万级数据秒级响应
  • 易部署:单个 Python 脚本即可运行,无需复杂基础设施
  • 可扩展:支持 CSV/JSON/Parquet/HTTP 等多种数据源

如果你正在寻找一个用技术变现的方向,这个方案值得深入尝试。

💡 想深入了解 DuckDB 在数据产品中的应用?duckdblab.org 上有完整的教程系列,涵盖从入门到实战的各个阶段。

📺 Watch video tutorials → Olap Studio YouTube

Subscribe for more DuckDB & AI automation tutorials

使用 Hugo 构建
主题 StackJimmy 设计

⚠️ 本站为独立社区项目,与 DuckDB 基金会及 DuckDB 官方项目无任何从属、背书或赞助关系。

"DuckDB" 是 DuckDB 基金会的注册商标,本站仅以事实描述方式使用该名称。

本站内容仅供教育与社区推广用途,不构成任何商业服务。