【问题标题】:Group by a result of case statement按案例陈述的结果分组
【发布时间】:2013-08-02 15:08:37
【问题描述】:

我正在尝试使用聚合函数和 case 语句进行查询以在我的 select 中工作,并在 case 语句上使用 group by 在 SQL Server 2005 中工作,但我似乎遗漏了一些东西。

declare @td int
set @td = 20130731

select 
    count(*) as total,
    case
       when dateadd(s, cdm.[StartTime], '19700101') >= '2013-07-31 00:00:00.000' and dateadd(s, cdm.[StartTime], '19700101') < '2013-07-31 01:00:00.000' 
        then '0-1'
    end as timestripe
FROM 
    [EXTERNAL_CDR].[dbo].[CDRMAIN] as cdm
WHERE 
    cdm.LocalDay = @td
    AND cdm.targetnum IN ('500','600')
GROUP BY
    timestripe

count(*) 部分有点弱,我知道,但问题在于 group by 语句。当我运行此查询时,我收到以下错误:

消息 207,第 16 级,状态 1,第 15 行
列名“timestripe”无效。

似乎 case 语句是错误的根本原因,但我不应该为了让它工作而编写子查询或加入。有什么想法吗?

【问题讨论】:

    标签: sql-server sql-server-2005 group-by case aggregate


    【解决方案1】:

    您不能在 GROUP BY 中引用别名,因此只需将整个 case 语句放入其中即可。去掉“as timestripe”部分。

    declare @td int
    set @td = 20130731
    
    select 
        count(*) as total,
        case
           when dateadd(s, cdm.[StartTime], '19700101') >= '2013-07-31 00:00:00.000' and dateadd(s, cdm.[StartTime], '19700101') < '2013-07-31 01:00:00.000' 
            then '0-1'
        end as timestripe
    FROM 
        [EXTERNAL_CDR].[dbo].[CDRMAIN] as cdm
    WHERE 
        cdm.LocalDay = @td
        AND cdm.targetnum IN ('500','600')
    GROUP BY
        case
           when dateadd(s, cdm.[StartTime], '19700101') >= '2013-07-31 00:00:00.000' and dateadd(s, cdm.[StartTime], '19700101') < '2013-07-31 01:00:00.000' 
            then '0-1'
        end
    

    【讨论】:

      【解决方案2】:

      对于这个查询,logical Processing Order of the SELECT statement 是:

      • 来自,
      • 在哪里
      • GROUP BY 和
      • 选择。

      因为SELECT 位于GROUP BY 之后,所以SELECT 子句中定义的所有别名(包括timestripe)都不能在上一步(GROUP BY)中使用。

      一种解决方案可能是:

      SELECT x.timestripe, COUNT(*) AS Cnt
      FROM (
      select 
          case
             when dateadd(s, cdm.[StartTime], '19700101') >= '2013-07-31 00:00:00.000' and dateadd(s, cdm.[StartTime], '19700101') < '2013-07-31 01:00:00.000' 
              then '0-1'
          end as timestripe
      FROM 
          [EXTERNAL_CDR].[dbo].[CDRMAIN] as cdm
      WHERE 
          cdm.LocalDay = @td
          AND cdm.targetnum IN ('500','600')
      ) x
      GROUP BY x.timestripe
      

      【讨论】:

      • 这个查询将最多生成两行:一行用于0-1,可能还有一行用于NULLtimestripe。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-09
      • 2023-04-10
      • 2010-10-30
      • 2016-05-13
      相关资源
      最近更新 更多