SQL语句求助:无y表匹配记录时如何返回x值与空白y值?
解决同年同月跨水库数据关联(含无数据场景)
你的核心需求是即使West水库(Dam15)没有对应月份的数据,也要保留East水库(Dam14)的记录,当前问题主要出在关联方式错误和y表CTE的逻辑混乱上,下面是针对性的修正方案:
问题拆解
- 关联逻辑错误:你使用了
INNER JOIN,这种关联会强制要求两边都有匹配数据才返回结果,换成LEFT JOIN才能保留x表的所有记录。 - y表CTE写法有误:原语句里的
Case试图返回多列(年份、水量、月份),不符合SQL语法;而且分组和子查询的逻辑完全混乱,应该直接按正常结构查询y表,哪怕结果为空也能保持正确的字段结构。 - 关联维度不全:只按月份名称关联会导致不同年份的同月份数据混淆,必须同时匹配
Survey_Year和月份(数字或名称)才能保证精准关联。
修正后的SQL语句
;WITH x AS ( SELECT [Survey_Year], Survey_Month, -- 保留月份数字,用于排序和精准关联 DateName(month, DateAdd(month, Survey_Month, -1)) as Month_Name, [Water_Volume] as East_Volume FROM Dam_Water_Levels WHERE Dam_Name = 14 AND [Survey_Date] > DATEADD(yyyy, -1, getdate()) ), y AS ( SELECT [Survey_Year], Survey_Month, DateName(month, DateAdd(month, Survey_Month, -1)) as Month_Name, [Water_Volume] as West_Volume FROM Dam_Water_Levels WHERE Dam_Name = 15 AND [Survey_Date] > DATEADD(yyyy, -1, getdate()) ) SELECT x.Month_Name as Month, x.East_Volume as East, ISNULL(y.West_Volume, '') as West -- 将NULL转为空白显示 FROM x LEFT JOIN y ON x.Survey_Year = y.Survey_Year AND x.Survey_Month = y.Survey_Month -- 按年份+月份精准匹配 ORDER BY x.Survey_Year, x.Survey_Month; -- 直接用月份数字排序,比关联Months表更高效
关键改进说明
- LEFT JOIN替代INNER JOIN:确保x表的所有记录都被保留,y表无匹配时对应字段自动显示
NULL,再通过ISNULL转为空白。 - 统一CTE结构:x和y的CTE保持相同的字段结构,让关联逻辑更清晰、易维护。
- 精准关联维度:同时匹配年份和月份,彻底避免不同年份的同月份数据错误关联。
- 简化排序逻辑:直接用
Survey_Month排序,不需要额外关联Months表;如果一定要用Months表,可改为左关联到x的月份字段,避免过滤掉x的记录。
这样修改后,即使Dam15没有符合条件的数据,Dam14的所有记录都会正常显示,West列会显示空白。
内容的提问来源于stack exchange,提问作者Tanya Geldenhuys
相关产品推荐
相关产品推荐

