You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

咨询:按指定产品家族与日期范围统计已售产品数量的最优方案

嘿,我来帮你梳理下这个统计需求的最优实现方式~

最优实现方案

针对你给出的模型结构,我从直接数据库查询(性能最优)和ORM框架实现两种常见场景来给方案,同时附上性能优化的关键点。

1. 直接SQL查询(大数据量首选)

直接通过数据库SQL完成关联、过滤和聚合是性能最高的方式,尤其是数据量较大时,能减少应用层的处理压力。

基础SQL查询(通用型)

适用于大多数关系型数据库(MySQL、PostgreSQL等):

SELECT 
    p.id AS product_id,
    CONCAT('product_', p.id) AS product_key,
    SUM(oi.amount) AS total_sold
FROM 
    "Order" o  -- 注意Order是关键字,部分数据库需要加引号
JOIN 
    OrderItem oi ON o.id = oi.order_id
JOIN 
    Product p ON oi.product_id = p.id
JOIN 
    Family f ON p.family_id = f.id
WHERE 
    o.placed_on BETWEEN '2024-01-01' AND '2024-01-07'  -- 替换为你的d1和d2
    AND f.id = 123  -- 替换为指定的家族ID
GROUP BY 
    p.id
ORDER BY 
    total_sold DESC;

这个查询会返回每个产品的ID、格式化后的键名和总销量,你可以在应用层把结果转换成你需要的[{"product_xxx": 数量}, ...]格式。

PostgreSQL专属优化(直接生成目标JSON)

如果用PostgreSQL,能直接在数据库层面生成你要的JSON结构,省去应用层转换步骤:

SELECT 
    json_agg(json_build_object(CONCAT('product_', p.id), SUM(oi.amount))) AS sales_data
FROM 
    "Order" o
JOIN 
    OrderItem oi ON o.id = oi.order_id
JOIN 
    Product p ON oi.product_id = p.id
JOIN 
    Family f ON p.family_id = f.id
WHERE 
    o.placed_on BETWEEN '2024-01-01' AND '2024-01-07'
    AND f.id = 123
GROUP BY 
    f.id;

执行后直接返回类似[{"product_24": 3435}, {"product_34": 56}]的结果,完全匹配你的输出需求。

2. ORM框架实现(以Django为例)

如果用ORM开发(比如Django、SQLAlchemy),代码更易维护,同时也能保证性能:

from django.db.models import Sum
from django.db.models.functions import Concat
from django.db.models import Value

# 配置参数:替换为你的家族ID和日期范围
target_family_id = 123
start_date = "2024-01-01"
end_date = "2024-01-07"

# 构建查询
sales_queryset = (
    Product.objects
    .filter(
        family_id=target_family_id,
        # 跨表过滤日期范围内的订单
        orderitem__order__placed_on__range=(start_date, end_date)
    )
    # 生成指定格式的产品键名,同时统计总销量
    .annotate(
        product_key=Concat(Value('product_'), 'id'),
        total_sold=Sum('orderitem__amount')
    )
    # 只保留需要的字段
    .values('product_key', 'total_sold')
)

# 转换成目标JSON格式
result = [{item['product_key']: item['total_sold']} for item in sales_queryset]

这个代码会直接生成你需要的列表嵌套字典结构,ORM会自动优化底层SQL,避免N+1查询问题。

3. 性能优化关键点

不管用哪种方式,这些优化能让你的查询更快:

  • 添加索引:给Order.placed_on、OrderItem.order_id、OrderItem.product_id、Product.family_id这几个字段建立索引,大幅提升JOIN和过滤的速度。
  • 预聚合(可选):如果数据量极大且实时性要求不高,可以每天定时跑统计任务,把各家族产品的销量存入专门的统计表,查询时直接读取预统计数据,性能提升非常明显。
  • 减少数据传输:尽量让数据库完成聚合和过滤,只返回需要的字段,避免把大量原始数据拉到应用层处理。

内容的提问来源于stack exchange,提问作者pzin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:23:24