如何按指定维度及状态/类型条件统计事实表行数?SQL问题求助
问题描述
需要统计FACT表中符合以下条件的行数:
- 关联DimLocation后,
DL.AVAILABILITY = 'A' - 关联DimMaterial后,
DE.MATERIAL_GROUP IN ('AAA', 'ABA', 'ABB') - 满足任一条件:
- DimMaterial的
MATERIAL_STATUS不为'MT100'(或为NULL) - FACT表的
ITEM_TYPE不为'ARM1'
(即:排除**同时满足MATERIAL_STATUS='MT100'且ITEM_TYPE='ARM1'**的记录,其余都统计)
- DimMaterial的
原SQL语句:
SELECT COUNT(*) FROM FACT JOIN DimLocation DL ON DL.LOCATION_ID = FACT.CKEY_LOCATION_ID JOIN DimMaterial DE ON DE.MAT_CODE = FACT.CKEY_MATERIAL_ID WHERE DL.AVAILABILITY = 'A' AND DE.MATERIAL_GROUP IN ('AAA', 'ABA', 'ABB') AND DE.MATERIAL_STATUS <> 'MT100' OR DE.MATERIAL_STATUS IS NOT NULL OR FACT.ITEM_TYPE <> 'ARM1'
执行后统计结果远大于仅满足前两个条件的行数,需要排查并修正。
问题排查
逻辑运算符优先级错误:SQL中
AND优先级高于OR,原WHERE子句被解析为:(DL.AVAILABILITY = 'A' AND DE.MATERIAL_GROUP IN (...) AND DE.MATERIAL_STATUS <> 'MT100') OR DE.MATERIAL_STATUS IS NOT NULL OR FACT.ITEM_TYPE <> 'ARM1'这导致只要满足
DE.MATERIAL_STATUS IS NOT NULL或者ITEM_TYPE <> 'ARM1'的记录都会被统计,完全忽略了前两个核心条件,结果自然远超预期。条件表达错误:原SQL中
DE.MATERIAL_STATUS IS NOT NULL和需求相反,需求是允许状态为NULL,这里反而把NULL的情况排除了;同时第三个条件的逻辑梳理混乱,没有正确匹配需求的“任一满足”规则。
修正后的SQL
写法一(直观排除法)
直接排除掉“状态为MT100且ITEM_TYPE为ARM1”的记录,可读性更高:
SELECT COUNT(*) FROM FACT JOIN DimLocation DL ON DL.LOCATION_ID = FACT.CKEY_LOCATION_ID JOIN DimMaterial DE ON DE.MAT_CODE = FACT.CKEY_MATERIAL_ID WHERE DL.AVAILABILITY = 'A' AND DE.MATERIAL_GROUP IN ('AAA', 'ABA', 'ABB') -- 排除同时满足两个否定条件的记录 AND NOT (DE.MATERIAL_STATUS = 'MT100' AND FACT.ITEM_TYPE = 'ARM1')
写法二(等价OR逻辑)
用括号包裹第三个条件的所有子规则,确保和前两个核心条件是AND关系:
SELECT COUNT(*) FROM FACT JOIN DimLocation DL ON DL.LOCATION_ID = FACT.CKEY_LOCATION_ID JOIN DimMaterial DE ON DE.MAT_CODE = FACT.CKEY_MATERIAL_ID WHERE DL.AVAILABILITY = 'A' AND DE.MATERIAL_GROUP IN ('AAA', 'ABA', 'ABB') AND (DE.MATERIAL_STATUS <> 'MT100' OR DE.MATERIAL_STATUS IS NULL OR FACT.ITEM_TYPE <> 'ARM1')
两种写法逻辑完全等价,可根据个人习惯选择。
内容的提问来源于stack exchange,提问作者lifeofthenoobie
相关产品推荐
相关产品推荐

