我想更好地理解以下查询中幕后发生的事情:
SELECT s.Question_Id, s.Question,
CASE WHEN
( SUM(CASE WHEN sr.Answer = 1 THEN 1 WHEN sr.Answer = 0 THEN 0 ELSE NULL END)
) IS NULL THEN 'N/A'
ELSE CAST(SUM(CASE WHEN sr.Answer = 1 THEN 1 WHEN sr.Answer = 0 THEN 0 ELSE NULL END) AS VARCHAR) END
AS Answered_Yes
FROM SurveyResult sr
INNER JOIN Survey s
ON sr.Question_Id = s.Question_Id
GROUP BY s.Question_Id, s.Question
为了更好地理解查询,它会返回一个调查结果,其总和为“是”答案。
注意:我正在执行CAST
,因为CASE
语句只能返回单个数据类型,而不是返回NULL,我想返回N / A.
所以我的问题是这一行(在ELSE
中):
CASE WHEN sr.Answer = 1 THEN 1 WHEN sr.Answer = 0 THEN 0 ELSE NULL END
实际上跑了两次?根据执行计划,它确实有一个额外的计算标量操作,但它是否使用缓存,因为它只是在WHEN
语句的第一次检查中完成相同的检查?
希望我的问题很明确,因为之前我已经有了这个场景,并想知道查询的性能影响。
答案 0 :(得分:2)
我不确定执行计划中的额外标量运算符,但您的查询可以像这样简化
SELECT s.Question_Id,
s.Question,
Isnull(cast(Sum(CASE sr.Answer
WHEN 1 THEN 1
WHEN 0 THEN 0
ELSE NULL
END) as varchar(100)), 'N/A') AS Answered_Yes
FROM SurveyResult sr
INNER JOIN Survey s
ON sr.Question_Id = s.Question_Id
GROUP BY s.Question_Id,
s.Question
但我猜执行计划仍然是一样的。
答案 1 :(得分:1)
首先,你永远不需要说," ELSE NULL"在CASE声明中;默认的ELSE行为是返回NULL值。接下来,如果SurveyResult.Answer只能是1或0,那么您的查询可以进一步简化为:
SELECT s.Question_Id,
s.Question,
Isnull(cast(Sum(sr.answer) as varchar(100)), 'N/A') AS Answered_Yes
FROM SurveyResult sr
INNER JOIN Survey s
ON sr.Question_Id = s.Question_Id
GROUP BY s.Question_Id, s.Question