【问题标题】:Why does GROUP BY not work with created column in select statement?为什么 GROUP BY 不适用于 select 语句中创建的列?
【发布时间】:2021-08-23 19:25:56
【问题描述】:

我有以下脚本

SELECT  
    CASE
        WHEN Grade < 4 
            THEN 'Fail'
        WHEN Grade >=4 and Grade < 6 
            THEN 'C'
        WHEN Grade >=6  and Grade < 8
            THEN 'Ok'
        ELSE 'Exc.'
    END AS [Status],
    COUNT(Grade) AS v
FROM
    GradeList
GROUP BY 
    [Status]

它没有看到Status 列。不知道为什么,有什么问题

【问题讨论】:

标签: sql sql-server tsql sql-server-2008


【解决方案1】:

这就是 SQL Server(和 SQL)的定义方式。在SELECT 中定义的列别名在FROMWHEREGROUP BY 子句中不可用。

对此有多种解决方案。我最喜欢的是使用APPLY,因为它定义了FROM 子句中的别名:

SELECT v.Status, COUNT(*) as v
FROM GradeList gl CROSS APPLY
     (VALUES (CASE WHEN Grade < 4 THEN 'Fail'
                   WHEN Grade < 6 THEN 'C'
                   WHEN Grade < 8 THEN 'Ok'
                   ELSE 'Exc.'
              END)
     ) v(Status)
GROUP BY v.Status;

请注意,这也简化了CASE 逻辑。返回第一个匹配条件,所以不需要BETWEEN。如果您想调整查询,这实际上使得添加和删除条件变得更加容易。

【讨论】:

    【解决方案2】:

    SQL Server 以特定的逻辑顺序处理 SQL 语句。由于 SELECT 子句在 GROUP BY 子句之后,因此 GROUP BY 子句看不到列别名。

    Read more on the logical processing order on MSDN

    1. 来自
    2. 开启
    3. 加入
    4. 在哪里
    5. 分组依据
    6. 使用多维数据集或使用汇总
    7. 选择
    8. 不同
    9. 订购人
    10. 顶部

    您可以使用派生表或公用表表达式来解决这个问题。

    SELECT Status, COUNT(Grade) AS v
    FROM
    (
    SELECT  
        CASE
            WHEN Grade < 4 
                THEN 'Fail'
            WHEN Grade >=4 and Grade < 6 
                THEN 'C'
            WHEN Grade >=6  and Grade < 8
                THEN 'Ok'
            ELSE 'Exc.'
        END AS [Status],
        Grade     
    FROM
        GradeList
    ) AS g(Status,Grade)
    GROUP BY 
        [Status]
    
    ;WITH cte_gradelist(Status,Grade) AS
    (
    SELECT  
        CASE
            WHEN Grade < 4 
                THEN 'Fail'
            WHEN Grade >=4 and Grade < 6 
                THEN 'C'
            WHEN Grade >=6  and Grade < 8
                THEN 'Ok'
            ELSE 'Exc.'
        END AS [Status],
        Grade     
    FROM
        GradeList
    )
    SELECT Status, COUNT(Grade) AS v
    FROM cte_gradelist
    GROUP BY 
        [Status]
    

    【讨论】:

      猜你喜欢
      • 2021-04-03
      • 1970-01-01
      • 1970-01-01
      • 2021-08-26
      • 2021-11-07
      • 1970-01-01
      • 2011-08-31
      • 2011-01-28
      • 2010-11-05
      相关资源
      最近更新 更多