如何按UNIT_QTY字段分组编写库存调拨统计SQL查询
嘿,我懂你的困扰——直接按UNIT_QTY分组时碰到了那个常见的SQL报错,对吧?这是因为SQL的分组规则有明确要求:SELECT语句里的所有非聚合字段,要么出现在GROUP BY子句里,要么被聚合函数(比如COUNT、MAX、SUM这类)包裹。你原来的查询里选了TRANS_BATCH_NO、FROM_BRANCH_ID这类字段,它们既没在GROUP BY里也没被聚合处理,数据库自然不知道该怎么处理这些字段的重复值。
结合你给出的原始数据和要填表格的需求,我给你几个不同场景的解决方案:
场景1:仅按UNIT_QTY统计调拨核心数据
如果只是想知道每个UNIT_QTY值对应多少条调拨记录、总调拨件数,可以用这个查询:
SELECT RPT_TRANSFERS.UNIT_QTY, COUNT(*) AS 调拨记录条数, SUM(RPT_TRANSFERS.UNIT_QTY) AS 总调拨件数 -- 可选:统计该数量档位的总件数 FROM [TISOREPORTS].[dbo].[RPT_TRANSFERS] LEFT JOIN RPT_BRANCHES ON RPT_TRANSFERS.TO_BRANCH_ID=RPT_BRANCHES.BRANCH_ID LEFT JOIN RPT_HIERARCHY_BY_SIZE ON RPT_TRANSFERS.SKU_ID=RPT_HIERARCHY_BY_SIZE.SKU_ID WHERE DATE_OUT between '2023-01-29' and '2023-02-04' AND FROM_BRANCH_ID = 1 AND TO_BRANCH_ID IN (2, 3, 4, 6, 7, 8,9, 10, 11, 12,13, 14, 15, 35,37, 45, 46, 47) GROUP BY RPT_TRANSFERS.UNIT_QTY ORDER BY RPT_TRANSFERS.UNIT_QTY;
它会返回类似这样的结果:
| UNIT_QTY | 调拨记录条数 | 总调拨件数 |
|---|---|---|
| 1 | 9 | 9 |
| 2 | 1 | 2 |
场景2:按UNIT_QTY+目标门店分组(更贴合表格需求)
如果你的表格需要区分不同门店的调拨数量统计,可以把目标门店相关字段也加入GROUP BY:
SELECT RPT_TRANSFERS.UNIT_QTY, RPT_TRANSFERS.TO_BRANCH_ID, RPT_BRANCHES.BRANCH_DESC, COUNT(*) AS 调拨记录条数, SUM(RPT_TRANSFERS.UNIT_QTY) AS 总调拨件数 FROM [TISOREPORTS].[dbo].[RPT_TRANSFERS] LEFT JOIN RPT_BRANCHES ON RPT_TRANSFERS.TO_BRANCH_ID=RPT_BRANCHES.BRANCH_ID LEFT JOIN RPT_HIERARCHY_BY_SIZE ON RPT_TRANSFERS.SKU_ID=RPT_HIERARCHY_BY_SIZE.SKU_ID WHERE DATE_OUT between '2023-01-29' and '2023-02-04' AND FROM_BRANCH_ID = 1 AND TO_BRANCH_ID IN (2, 3, 4, 6, 7, 8,9, 10, 11, 12,13, 14, 15, 35,37, 45, 46, 47) GROUP BY RPT_TRANSFERS.UNIT_QTY, RPT_TRANSFERS.TO_BRANCH_ID, RPT_BRANCHES.BRANCH_DESC ORDER BY RPT_TRANSFERS.UNIT_QTY, RPT_TRANSFERS.TO_BRANCH_ID;
这样你就能得到每个门店、每个调拨数量对应的统计数据,直接填入表格就行。
补充:为什么原来的写法会报错?
再简单说下那个错误的原因:当你用GROUP BY UNIT_QTY时,数据库会把所有UNIT_QTY相同的行合并成一行,但你原来的查询里有TRANS_BATCH_NO(每个批次号都不一样)、SKU_ID(每个SKU也不同)这类字段,数据库不知道该取这些字段的哪一个值来对应分组后的行,所以必须要么用聚合函数(比如MAX(TRANS_BATCH_NO)取该组最大的批次号),要么把这些字段也加入GROUP BY(但那样分组粒度就变细了,不再是仅按UNIT_QTY分组)。
如果你的表格还需要按SKU类别(COMP、RET_GRP)统计,只需要把对应的字段加入GROUP BY和SELECT里就行,原理都是一样的。
备注:内容来源于stack exchange,提问作者JakeClayton45

