SQL需求:基于Location列拆分Qty求和,仅保留存在Storage的物品
SQL查询问题:筛选存在Storage位置的物品并统计数量
需求
- 仅列出存在Storage位置记录的物品
- 统计每个物品在Storage和Active位置的Qty总和
- 排除不在Storage/Active位置的物品(如示例中的ItemC)
数据集示例
| ID | Item | Location | Qty |
|---|---|---|---|
| 1 | ItemA | Storage | 4 |
| 2 | ItemA | Active | 9 |
| 3 | ItemB | Storage | 3 |
| 4 | ItemB | Storage | 2 |
| 5 | ItemA | Active | 1 |
| 6 | ItemC | Boxed | 3 |
| 7 | ItemD | Active | 1 |
| 8 | ItemD | Storage | 1 |
预期结果
| Item | Storage | Active |
|---|---|---|
| ItemA | 4 | 10 |
| ItemB | 5 | 0 |
| ItemD | 1 | 1 |
错误尝试代码及问题
尝试的SQL代码:
SELECT ITEMDESC.A, SUM(CASE WHEN LOCATION.A='Storage' THEN QTY.A ELSE 0 END), SUM(CASE WHEN LOCATION.B='Active' THEN QTY.B ELSE 0 END) FROM ITEMS A, ITEMS B INNER JOIN ITEMDESC.A = ITEMDESC.B WHERE GROUP BY ITEMDESC.A
遇到的问题:
- 该查询返回所有物品,不符合筛选要求
- 添加
WHERE Location.B = 'Storage'后,仅能统计Storage的数量,Active数量全部为0,无法得到正确结果
正确SQL写法及说明
实现思路
- 先过滤掉无关位置的记录(仅保留Storage和Active),提升查询效率
- 按Item分组,用
CASE WHEN分别统计两个位置的Qty总和 - 用
HAVING子句过滤出存在Storage记录的物品(分组后判断Storage的总和大于0)
代码
SELECT Item, SUM(CASE WHEN Location = 'Storage' THEN Qty ELSE 0 END) AS Storage, SUM(CASE WHEN Location = 'Active' THEN Qty ELSE 0 END) AS Active FROM ITEMS WHERE Location IN ('Storage', 'Active') GROUP BY Item HAVING SUM(CASE WHEN Location = 'Storage' THEN Qty ELSE 0 END) > 0
错误原因解析
- 原代码使用了不必要的自连接(
ITEMS A, ITEMS B),导致逻辑混乱,无法正确统计 - 直接在
WHERE中过滤Location='Storage'会丢失Active位置的记录,因此无法统计该位置的数量,必须用HAVING在分组后筛选存在Storage记录的物品,而非提前过滤数据
内容的提问来源于stack exchange,提问作者Bagelwinner
相关产品推荐
相关产品推荐

