SQL Server:分组无对应行时返回NULL而非0的实现方案
解决未参与轮次返回NULL的SQL报表问题
要区分「参赛者未参与某轮」和「参与但无奖金」这两种情况,核心是先构建所有参赛者 + 所有轮次的完整组合,再通过左连接原表来统计,这样未参与的轮次自然会返回NULL,而参与但无奖金的会返回0。
具体实现思路
- 生成包含所有游戏轮次的数据集(固定为1、2、3);
- 提取所有唯一的参赛者名单;
- 将两者交叉连接,得到每个参赛者对应每一轮的完整组合;
- 左连接原
GameWinnings表,匹配参赛者和轮次; - 按参赛者分组,对每轮的奖金求和——左连接后无匹配的轮次,
SUM()会返回NULL;有匹配但奖金为0的则返回0,完美区分两种场景。
优化后的SQL查询
WITH AllRounds AS ( -- 生成所有游戏轮次 SELECT GameRound FROM (VALUES (1), (2), (3)) AS Rounds(GameRound) ), AllContestants AS ( -- 提取所有唯一参赛者 SELECT DISTINCT Contestant FROM dbo.GameWinnings ) SELECT ac.Contestant, SUM(CASE WHEN ar.GameRound = 1 THEN gw.RoundWinningsAmount END) AS Round_1_Winnings, SUM(CASE WHEN ar.GameRound = 2 THEN gw.RoundWinningsAmount END) AS Round_2_Winnings, SUM(CASE WHEN ar.GameRound = 3 THEN gw.RoundWinningsAmount END) AS Round_3_Winnings FROM AllContestants ac CROSS JOIN AllRounds ar LEFT JOIN dbo.GameWinnings gw ON ac.Contestant = gw.Contestant AND ar.GameRound = gw.GameRound GROUP BY ac.Contestant
结果匹配验证
- Mr Wang:第1轮返回对应奖金,第2轮参与但无奖金(返回0),第3轮未参与(返回NULL);
- Ms Junaiqua:仅第2轮参与(返回0),第1、3轮未参与(返回NULL);
- Thad Chad:全部3轮都参与,返回对应奖金合计值。
内容的提问来源于stack exchange,提问作者Shiva
相关产品推荐
相关产品推荐

