Oracle SQL查询单表缺失记录:找出物品未覆盖的指定位置
问题分析与解决方案
原语句的错误主要有两点:
- CTE
Sku只定义了5个位置,没有包含物品(Item)数据,所以t.Item是无效列,且你要关联的应该是实际存储物品位置的业务表,而非自己定义的Sku CTE。 - Oracle的JOIN语法不支持在JOIN后面直接加
PARTITION BY,这是窗口函数的语法,放在此处会触发"Missing Keyword"错误。
正确的思路是:先生成所有物品与指定5个位置的全量组合,再排除掉已经存在的组合,剩下的就是每个物品缺失的位置。假设你的业务表叫ITEM_LOCATIONS,包含Item(物品编号)和Loc(位置)字段,修正后的SQL如下:
WITH REQUIRED_LOCS (Loc) AS ( SELECT 'Loc1' FROM DUAL UNION ALL SELECT 'Loc2' FROM DUAL UNION ALL SELECT 'Loc3' FROM DUAL UNION ALL SELECT 'Loc4' FROM DUAL UNION ALL SELECT 'Loc5' FROM DUAL ), ALL_ITEMS (Item) AS ( SELECT DISTINCT Item FROM ITEM_LOCATIONS ) SELECT ai.Item, rl.Loc FROM ALL_ITEMS ai CROSS JOIN REQUIRED_LOCS rl LEFT JOIN ITEM_LOCATIONS il ON ai.Item = il.Item AND rl.Loc = il.Loc WHERE il.Loc IS NULL ORDER BY ai.Item, rl.Loc;
语句说明:
REQUIRED_LOCS:生成你关注的5个指定位置。ALL_ITEMS:提取业务表中所有唯一的物品,确保覆盖所有需要检查的物品。CROSS JOIN:生成每个物品与5个位置的全量组合,这是理论上应该存在的所有分布。LEFT JOIN+WHERE il.Loc IS NULL:筛选出那些理论上应该存在,但实际业务表中没有记录的物品-位置对,也就是缺失的位置。
如果你的业务表名称或字段名不同,替换成实际的即可。
内容的提问来源于stack exchange,提问作者redoctober
相关产品推荐
相关产品推荐

