无法按首次发货日期统计发货总数量的SQL问题排查
错误原因
你的SQL存在两处逻辑问题:
- 子查询t1分组规则错误:按
item+Quantity分组会将同一物料、同一最早交付日期下不同数量的记录拆分为独立行,关联后仅能匹配到单条数量记录,无法得到汇总值,这也是你第一次查询只返回单条数量的原因。 - 直接加
sum(Quantity)得到错误结果,是因为关联时产生了重复行:同一物料同一最早交付日期下的多条数量记录和t2关联时会出现笛卡尔积,求和时数量被重复计算,比如物料A在15-Jul的20、25两条记录会被重复累加得到60,和实际值不符。
正确实现方案
不需要复杂的自关联分组,以下两种写法都可以得到正确结果,你可以根据自己用的数据库版本选择:
通用兼容写法(支持所有SQL版本)
先通过子查询算出每个物料的最早交付日期,再关联原表汇总该日期下的总数量:
SELECT t_min.item, t_min.edd AS date, SUM(s.quantity) AS Quantity FROM ( SELECT item, MIN(EDD) AS edd FROM shipment GROUP BY item ) AS t_min JOIN shipment s ON t_min.item = s.item AND t_min.edd = s.EDD GROUP BY t_min.item, t_min.edd;
窗口函数写法(支持MySQL8.0+、PostgreSQL、SQL Server等主流数据库新版本)
用窗口函数直接标记出每个物料对应最早交付日期的记录,再筛选汇总即可,逻辑更直观:
WITH shipment_rn AS ( SELECT item, EDD AS date, quantity, ROW_NUMBER() OVER (PARTITION BY item ORDER BY EDD) AS rn FROM shipment ) SELECT item, date, SUM(quantity) AS Quantity FROM shipment_rn WHERE rn = 1 GROUP BY item, date;
运行结果
上述语句执行后会返回你期望的结果:
| Item | date | Quantity |
|---|---|---|
| A | 15-Jul | 45 |
| B | 20-Jul | 20 |
| C | 25-Jul | 5 |
内容的提问来源于stack exchange,提问作者Yunus Surty
相关产品推荐
相关产品推荐

