Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server---如何按SELECT语句中CASE语句中声明的列进行分组_Sql_Sql Server_Case - Fatal编程技术网

SQL Server---如何按SELECT语句中CASE语句中声明的列进行分组

SQL Server---如何按SELECT语句中CASE语句中声明的列进行分组,sql,sql-server,case,Sql,Sql Server,Case,我在按列分组[评分]时遇到问题。当我执行它时,它给出了“无效的列名‘rate’” 有人能帮我吗?谢谢 SELECT ...... CASE WHEN level_1 = 'Corporate' THEN CASE WHEN ssr.rating = 'A' OR ssr.rating LIKE 'A[+-]' THEN 'Corp A' WHEN

我在按列分组[评分]时遇到问题。当我执行它时,它给出了“无效的列名‘rate’”

有人能帮我吗?谢谢

SELECT
     ......
   CASE
         WHEN level_1 = 'Corporate'
         THEN 
            CASE
            WHEN ssr.rating = 'A' OR ssr.rating LIKE 'A[+-]'
            THEN 'Corp A'

            WHEN ssr.rating = 'AA' OR ssr.rating LIKE 'AA[+-]'
            THEN 'Corp AA'

            WHEN ssr.rating = 'BBB' OR ssr.rating LIKE 'BBB[+-]'
            THEN 'Corp BBB'

            ELSE NULL
        END

            WHEN level_1 = 'Government' AND level_2 = 'Provincial'
            THEN 'Prov'

            WHEN level_1 = 'Government' AND level_2 = 'Federal'
            THEN 'Canada'

       ELSE NULL
   END AS rating,
     ......
  SUM(...)
     .......
FROM....
GROUP BY rating

要么将其设置为派生表(也称为子查询),要么重复整个表达式(不要担心SQL Server会计算一次并多次使用它)

在您的例子中,只需重复case表达式看起来更容易

SELECT
     ......
   CASE
         WHEN level_1 = 'Corporate'
         THEN 
            CASE
            WHEN ssr.rating = 'A' OR ssr.rating LIKE 'A[+-]'
            THEN 'Corp A'

            WHEN ssr.rating = 'AA' OR ssr.rating LIKE 'AA[+-]'
            THEN 'Corp AA'

            WHEN ssr.rating = 'BBB' OR ssr.rating LIKE 'BBB[+-]'
            THEN 'Corp BBB'

            ELSE NULL
        END

            WHEN level_1 = 'Government' AND level_2 = 'Provincial'
            THEN 'Prov'

            WHEN level_1 = 'Government' AND level_2 = 'Federal'
            THEN 'Canada'

       ELSE NULL
   END AS rating,
     ......
  SUM(...)
     .......
FROM....
GROUP BY CASE
         WHEN level_1 = 'Corporate'
         THEN 
            CASE
            WHEN ssr.rating = 'A' OR ssr.rating LIKE 'A[+-]'
            THEN 'Corp A'

            WHEN ssr.rating = 'AA' OR ssr.rating LIKE 'AA[+-]'
            THEN 'Corp AA'

            WHEN ssr.rating = 'BBB' OR ssr.rating LIKE 'BBB[+-]'
            THEN 'Corp BBB'

            ELSE NULL
        END

            WHEN level_1 = 'Government' AND level_2 = 'Provincial'
            THEN 'Prov'

            WHEN level_1 = 'Government' AND level_2 = 'Federal'
            THEN 'Canada'

       ELSE NULL
   END

您可以使用子查询,或者像Richard提到的那样重复它,或者使用
公共表表达式
,在我看来,它更具可读性:

WITH cte 
     AS (SELECT CASE 
                  WHEN level_1 = 'Corporate' THEN 
                    CASE 
                      WHEN ssr.rating = 'A' 
                            OR ssr.rating LIKE 'A[+-]' THEN 'Corp A' 
                      WHEN ssr.rating = 'AA' 
                            OR ssr.rating LIKE 'AA[+-]' THEN 'Corp AA' 
                      WHEN ssr.rating = 'BBB' 
                            OR ssr.rating LIKE 'BBB[+-]' THEN 'Corp BBB' 
                      ELSE NULL 
                    END 
                  WHEN level_1 = 'Government' 
                       AND level_2 = 'Provincial' THEN 'Prov' 
                  WHEN level_1 = 'Government' 
                       AND level_2 = 'Federal' THEN 'Canada' 
                  ELSE NULL 
                END AS rating -- other columns ...
         FROM   dbo.tablename) 
SELECT cte.*, 
       Sum(col)AS ColSum 
FROM   cte 
GROUP  BY rating 

我发现最简单的方法就是使用子查询:

select rating, .  .
from (SELECT
     ......
   CASE
         WHEN level_1 = 'Corporate'
         THEN 
            CASE
            WHEN ssr.rating = 'A' OR ssr.rating LIKE 'A[+-]'
            THEN 'Corp A'

            WHEN ssr.rating = 'AA' OR ssr.rating LIKE 'AA[+-]'
            THEN 'Corp AA'

            WHEN ssr.rating = 'BBB' OR ssr.rating LIKE 'BBB[+-]'
            THEN 'Corp BBB'

            ELSE NULL
        END

            WHEN level_1 = 'Government' AND level_2 = 'Provincial'
            THEN 'Prov'

            WHEN level_1 = 'Government' AND level_2 = 'Federal'
            THEN 'Canada'

       ELSE NULL
   END AS rating,
   *
 from . . .
) t
group by rating;

这适用于所有数据库,包括MySQL和Access。缺点是有些数据库将子查询视为派生表,并实际保存中间结果。不考虑糟糕的SQL引擎实现。在这种情况下,如果希望避免这种开销,则需要在
groupby
语句中重复这种情况。而且,在
组中确实存在接受
评级的数据库,但很少。

。。。或者使用
通用表表达式
。谢谢!!!它起作用了,但我还是不明白为什么我们必须一组一组地重复整个表达式clause@Tim我提到了派生表,它可以是您提到的CTE,也可以只是一个常规子查询。我认为有一种方法可以将case语句作为模板,然后将模板参数插入到代码中,以消除代码的重复。我该怎么做1