SQL分组子查询中去除Null值并替换为0的实现方法求助
解决GROUP BY后子查询返回Null值替换为0的问题
看起来你是想按日期汇总不同停机类型的总时长,但当前的SQL因为分组逻辑和子查询的问题导致出现了Null值,我来帮你搞定这个问题:
核心问题分析
你的SQL存在两个关键问题:
- 分组时包含了
EnumArret,导致结果变成「日期+停机类型」的组合行,每个行只会对应一种类型,其他类型自然没有数据返回Null; - 子查询没有关联当前分组的日期,相当于全局筛选,无法准确匹配当前行的日期范围。
推荐方案:使用条件聚合(高效简洁)
这种方式直接在分组内对每个类型进行条件求和,没有匹配的记录就返回0,完美解决Null问题:
SELECT CONVERT(varchar, apj.DateArret, 3) AS [Date Arrêt], -- 统计HH类型总时长,无匹配则取0 SUM(CASE WHEN apj.EnumArret LIKE 'HH' THEN DATEDIFF(minute, apj.HeureDebut, apj.HeureFin) ELSE 0 END) AS HH, -- 统计HI类型总时长,无匹配则取0 SUM(CASE WHEN apj.EnumArret LIKE 'HI' THEN DATEDIFF(minute, apj.HeureDebut, apj.HeureFin) ELSE 0 END) AS HI, -- 统计PS类型总时长,无匹配则取0 SUM(CASE WHEN apj.EnumArret LIKE 'PS' THEN DATEDIFF(minute, apj.HeureDebut, apj.HeureFin) ELSE 0 END) AS PS FROM dbo.ArretProductionJournee apj -- 建议用ISO日期格式(YYYYMMDD),避免不同语言环境下的日期解析歧义 WHERE apj.DateArret BETWEEN '20210401' AND '20210403' -- 只按日期分组,确保每天一行数据 GROUP BY CONVERT(varchar, apj.DateArret, 3) -- 按日期排序,结果更清晰 ORDER BY CONVERT(varchar, apj.DateArret, 3)
备选方案:用ISNULL包裹关联子查询
如果你更习惯子查询写法,可以给子查询添加日期关联条件,并用ISNULL()将Null替换为0:
SELECT CONVERT(varchar, apj.DateArret, 3) AS [Date Arrêt], -- 关联当前日期,无数据则返回0 ISNULL((SELECT SUM(DATEDIFF(minute, apj2.HeureDebut, apj2.HeureFin)) FROM dbo.ArretProductionJournee apj2 WHERE apj2.DateArret = apj.DateArret AND apj2.EnumArret LIKE 'HH'), 0) AS HH, ISNULL((SELECT SUM(DATEDIFF(minute, apj2.HeureDebut, apj2.HeureFin)) FROM dbo.ArretProductionJournee apj2 WHERE apj2.DateArret = apj.DateArret AND apj2.EnumArret LIKE 'HI'), 0) AS HI, ISNULL((SELECT SUM(DATEDIFF(minute, apj2.HeureDebut, apj2.HeureFin)) FROM dbo.ArretProductionJournee apj2 WHERE apj2.DateArret = apj.DateArret AND apj2.EnumArret LIKE 'PS'), 0) AS PS FROM dbo.ArretProductionJournee apj WHERE apj.DateArret BETWEEN '20210401' AND '20210403' GROUP BY CONVERT(varchar, apj.DateArret, 3) ORDER BY CONVERT(varchar, apj.DateArret, 3)
内容的提问来源于stack exchange,提问作者Kessar Mohamed
相关产品推荐
相关产品推荐

