按日期分组统计如何展示计数为NULL的日期?SQL查询问题求助
问题分析与解决方案
咱们来一步步拆解你遇到的两个核心问题:
1. 为什么LEFT JOIN后仍跳过计数为NULL的日期?
你当前的查询逻辑里,LEFT OUTER JOIN Pattern之后紧接着用了两个INNER JOIN连接Result和Detail——这直接破坏了LEFT JOIN的预期效果。因为INNER JOIN要求关联的两张表必须有匹配的记录,所以:
- 当
CalendarMain的日期没有对应的Pattern记录时,p.PatternID会是NULL,后续的INNER JOIN会直接把这条记录过滤掉 - 即使有
Pattern记录,但对应的Result或Detail不满足r.Type=7或d.Panel=501时,同样会被INNER JOIN筛掉
解决办法:把两个INNER JOIN改成LEFT JOIN,同时将WHERE里的条件移到对应的JOIN的ON子句中,这样过滤逻辑只会作用于关联表,不会影响CalendarMain的所有日期:
SELECT CAST(c.DT AS DATE) AS 'Date', COUNT(p.PatternID) AS 'Count' FROM CalendarMain c LEFT OUTER JOIN Pattern p ON CAST(c.DT AS DATE) = CAST(p.PatternDate AS DATE) -- 转DATE忽略时间部分 LEFT JOIN Result r ON p.PatternID = r.PatternID AND r.Type = 7 -- 将条件移到ON子句,避免过滤主表日期 LEFT JOIN Detail d ON p.PatternID = d.PatternID AND d.Panel = 501 -- 将条件移到ON子句,避免过滤主表日期 WHERE CAST(c.DT AS DATE) BETWEEN '20190101' AND '20190201' GROUP BY CAST(c.DT AS DATE) ORDER BY CAST(c.DT AS DATE)
这里用COUNT(p.PatternID)而非COUNT(*),是因为当没有匹配的Pattern时,p.PatternID为NULL,COUNT会自动忽略NULL值,得到正确的0;如果用COUNT(*)会统计所有行(包括NULL行),结果会变成1,不符合计数需求。
2. 为什么直接用c.DT = p.PatternDate无结果返回?
虽然两者都是DateTime类型,但CalendarMain的c.DT是每日的固定记录,应该是当天的00:00:00(比如2019-01-01 00:00:00.000),而p.PatternDate大概率包含具体的时间部分(比如2019-01-01 14:30:22.123)。直接用等于比较时,只有当两个DateTime的秒甚至毫秒都完全一致才会匹配,自然就没有结果。
而转成DATE类型后,会自动忽略时间部分,只比较年月日,这样就能正确匹配同一天的所有记录。
内容的提问来源于stack exchange,提问作者user10643040
相关产品推荐
相关产品推荐

