第二个CASE语句如何影响性能

时间:2016-11-02 15:28:54

标签: sql sql-server tsql case case-when

我想更好地理解以下查询中幕后发生的事情:

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语句的第一次检查中完成相同的检查?

希望我的问题很明确,因为之前我已经有了这个场景,并想知道查询的性能影响。

2 个答案:

答案 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