SQL Server两临时表对应列除法运算问题求解
解决临时表计算Closing %时行数超出预期的问题
问题根源
行数超出预期基本是因为表连接时没指定精准的Grp等值匹配条件,导致产生笛卡尔积(比如两个表各3行,无匹配条件的连接会生成9行)。必须基于Grp列做一对一匹配,才能得到预期的3行结果。
正确实现代码
直接通过等值连接生成目标表,同时处理除数为0的异常情况:
-- 生成Closing_PC表,确保每个Grp仅匹配一次 SELECT CONCAT('Closing % ', s.Grp) AS Grp, -- 避免除数为0报错,无意义的结果设为NULL CASE WHEN t.Days = 0 THEN NULL ELSE s.Days / t.Days END AS Days, CASE WHEN t.Weeks = 0 THEN NULL ELSE s.Weeks / t.Weeks END AS Weeks, CASE WHEN t.Months = 0 THEN NULL ELSE s.Months / t.Months END AS Months, CASE WHEN t.Years = 0 THEN NULL ELSE s.Years / t.Years END AS Years INTO Closing_PC FROM #Temp_Sales_subvenue s INNER JOIN #Temp_tour_subvenue t ON s.Grp = t.Grp; -- 核心:通过Grp等值连接,杜绝笛卡尔积
额外注意事项
- 如果
#Temp_tour_subvenue中存在重复的Grp值,需要先做聚合(比如GROUP BY Grp取总和/平均值),否则连接后仍会出现多行 - 若要保留
#Temp_Sales_subvenue中存在但#Temp_tour_subvenue中没有的Grp,可将INNER JOIN改为LEFT JOIN,此时对应计算列会返回NULL - 如果需要用CTE写法,逻辑完全一致,只是把查询包在CTE里:
WITH Closing_CTE AS ( SELECT CONCAT('Closing % ', s.Grp) AS Grp, CASE WHEN t.Days = 0 THEN NULL ELSE s.Days / t.Days END AS Days, CASE WHEN t.Weeks = 0 THEN NULL ELSE s.Weeks / t.Weeks END AS Weeks, CASE WHEN t.Months = 0 THEN NULL ELSE s.Months / t.Months END AS Months, CASE WHEN t.Years = 0 THEN NULL ELSE s.Years / t.Years END AS Years FROM #Temp_Sales_subvenue s INNER JOIN #Temp_tour_subvenue t ON s.Grp = t.Grp ) SELECT * INTO Closing_PC FROM Closing_CTE;
内容的提问来源于stack exchange,提问作者Burt Ox
相关产品推荐
相关产品推荐

