【问题标题】:SQL Server transpose a query resultSQL Server 转置查询结果
【发布时间】:2017-04-05 17:32:51
【问题描述】:

我有一个包含以下数据的表格:

ItemId  PendingTime
1       2016-11-23 15:57:56.000
2       2016-07-09 17:33:09.000
3       2015-11-27 18:34:03.000

等等..

我想知道自过去 30 分钟、过去 1 小时、过去 1 周、过去 1 个月和一年多以来待处理的项目总和。我想出了以下查询:

SELECT
    SUM(CASE 
           WHEN datediff(MINUTE, PENDING_TIME,GETDATE()) <= 30 
              THEN 1 ELSE 0 
        END) AS '30 Min',
Sum(case when (datediff(MINUTE,PENDING_TIME, GETDATE())) > 30 AND (datediff(MINUTE,PENDING_TIME, GETDATE())) <= 60 then 1 Else 0 End) as 'Over 30 Min',
Sum(case when (datediff(MINUTE,PENDING_TIME, GETDATE())) > 60 AND (datediff(HOUR,PENDING_TIME, GETDATE())) <= 24 then 1 Else 0 End) as 'Over 1 Hr',
Sum(case when (datediff(DAY,PENDING_TIME, GETDATE())) > 1 AND (datediff(DAY,PENDING_TIME, GETDATE())) < 30 then 1 Else 0 End) as '1 month',
Sum(case when datediff(DAY,PENDING_TIME, GETDATE()) >= 30 then 1 Else 0 End) as 'More than month'
from ItemsTable where datepart(yyyy,PENDING_TIME) = DATEPART(yyyy,GETDATE())

这会将数据返回为:

30 Min      Over 30 Min Over 1 Hr   1 month     More than month
----------- ----------- ----------- ----------- ---------------
100          350        NULL        NULL        NULL

我希望 2 列格式的结果为:

30 Min       ------     45
Over 30      ------    100
Over 1 hr    ------    null
Over 1 month ------    null

我知道数据透视函数,但是我选择的列实际上并不在我从中选择的表中,而是作为聚合函数的结果创建的。

如何以 2 列和多行格式获取此信息。

感谢您通读。

【问题讨论】:

    标签: sql-server pivot transpose


    【解决方案1】:

    您可以创建一个派生列,将等待分类为不同类型,然后按该列分组:

    With waitCodes As (
        Select Case
             When DateDiff(Minute, PENDING_TIME, GetDate()) <= 30 Then '30 Min'
             When DateDiff(Minute, PENDING_TIME, GetDate()) <= 60 Then 'Over 30'
             When DateDiff(Minute, PENDING_TIME, GetDate()) <= 1440 Then 'Over 1 hr'
             When DateDiff(Minute, PENDING_TIME, GetDate()) <= 43200 Then '1 month'
             Else 'More than a month' End As [WaitTime]
          From ItemsTable
          Where DatePart(yyyy, PENDING_TIME) = DatePart(yyyy,GetDate()))
    Select [WaitTime], Count(*) As n
      From waitCodes
      Group By [WaitTime];
    

    此外,我强烈建议您更改查询中的Where 子句,以便它不会将函数应用于PENDING_TIME 列。 There are multiple benefits of this.

    ...
    Where PENDING_TIME >= Convert(date, Convert(char(4), DatePart(yyyy, GetDate()))+'-01-01 00:00:00.000', 121)
      And PENDING_TIME < Convert(date, Convert(char(4), DatePart(yyyy, GetDate())+1)+'-01-01 00:00:00.000', 121)
    ....
    

    【讨论】:

    • 不错的解决方案。顺便说一句,替代的 WHERE 子句仅在相关表没有未来日期时才有效。
    • @wdosanjos 好点。我假设这种情况不会发生,但这可能是一个危险的假设。我已经相应地编辑了建议的WHERE
    • 顺便说一句,看看here,了解如何在不进行字符串操作的情况下获取一年中的第一天和最后几天的解决方案。 Where PENDING_TIME &gt;= DATEADD(yy, DATEDIFF(yy,0,getdate()), 0) and PENDING_TIME &lt; DATEADD(yy, DATEDIFF(yy,0,getdate()) + 1, 0)
    • @mendosi:非常好。使用 sql2014,查询不起作用。但是,我将案例修改为: Select Case When DateDiff(Minute, PENDING_TIME, GetDate())
    • @user1101987 是的,谢谢。我把它写在我的手机上,所以忘了你不能在一个简单的CASE 表达式中使用不等式比较。已更新。
    【解决方案2】:

    您可以像这样对每个原始 sql 使用交叉应用语句

        SELECT c.* FROM 
        (
            SELECT
               SUM(CASE 
                   WHEN datediff(MINUTE, PENDING_TIME,GETDATE()) <= 30 
                      THEN 1 ELSE 0 
                END) AS '30 Min',
              Sum(case when (datediff(MINUTE,PENDING_TIME, GETDATE())) > 30 AND (datediff(MINUTE,PENDING_TIME, GETDATE())) <= 60 then 1 Else 0 End) as 'Over 30 Min',
              Sum(case when (datediff(MINUTE,PENDING_TIME, GETDATE())) > 60 AND (datediff(HOUR,PENDING_TIME, GETDATE())) <= 24 then 1 Else 0 End) as 'Over 1 Hr',
              Sum(case when (datediff(DAY,PENDING_TIME, GETDATE())) > 1 AND (datediff(DAY,PENDING_TIME, GETDATE())) < 30 then 1 Else 0 End) as '1 month',
              Sum(case when datediff(DAY,PENDING_TIME, GETDATE()) >= 30 then 1 Else 0 End) as 'More than month'
            from ItemsTable where datepart(yyyy,PENDING_TIME) = DATEPART(yyyy,GETDATE())
        )
        CROSS APPLY(VALUES('30 MIN',a),('Over 30',b),('Over 1 hr',c),('Over 1 month',d),('More than month',e)) c(title,[value])
    

    结果:

    标题值 --------------- ------------ 30 分钟 100 超过 30 350 超过 1 小时 NULL 超过 1 个月 NULL 超过一个月 NULL

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-23
      • 2021-10-30
      • 1970-01-01
      • 2018-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-15
      相关资源
      最近更新 更多