1

我有类似的数据

我的表

person   datetimeField   datavalue1
 a        20110104        3
 a2       20110105        2 
 b        20110302        5
 c        20110403        6
 d        20110605        2

最终结果应如下所示:(顺序不重要)

 DatePart    SumDatavalue1
 January      5
 March        5
 April        6
 June         2
 Quarter1     10
 Quarter2     8

我能想到的唯一方法是使用两个单独的选择语句和 GROUP BY,然后执行 UNION ALL。有没有更有效的方法?

编辑:我应该说可能还有另一列 datavalue2 需要平均,而不是求和。不确定这是否会有所作为。

4

2 回答 2

4

是的,你可以做到。这就是grouping sets设计的目的。这是执行您想要的 SQL 的示例:

select (case when datename(mm, dt) is null
             then qtr
             else datename(mm, dt)
        end), count(*), sum(val)
from (select t.*,
             'Quarter'+cast(datepart(qq, dt) as varchar(255)) as qtr
      from temp t
     ) t
group by grouping sets((datename(mm, dt)),
                       (qtr))
order by (case when qtr is null then 0 else 1 end),
         min(dt)

SQLFiddle 在这里

针对您的评论,grouping setsrollup(and cube) 的概括。您grouping sets可以像这样添加总数:

select (case when datename(mm, dt) is null and qtr is null
             then 'Total'
             when datename(mm, dt) is null
             then qtr
             else datename(mm, dt)
        end), count(*), sum(val)
from (select t.*,
             'Quarter'+cast(datepart(qq, dt) as varchar(255)) as qtr
      from temp t
     ) t
group by grouping sets((datename(mm, dt)),
                       (qtr),
                       ())
order by (case when qtr is null and datename(mm, dt) is null then 2
               when datename(mm, dt) is null then 1
               else 0
          end),
         min(dt)

主要的复杂性是在第一列中打印出正确的值并正确排序。

于 2013-06-13T15:55:10.523 回答
2

对 SubTotals 使用 ROLLUP ...它很有效,因为它只遍历详细数据一次,这与 2 个单独的 GroupBys 不同

 SELECT CASE WHEN [DATEPART] IS NULL THEN 'Quarter' + CONVERT(VARCHAR(10),QQ)
             ELSE [DATEPART] END [DatePart], [SumDataValue1] 
 FROM  (
         SELECT DATENAME(mm, dateTimefield ) [DATEPART],DATENAME(qq, dateTimefield ) [QQ] , SUM(datavalue1) [SumDataValue1] 
         FROM MyTable
         GROUP BY DATENAME(qq, dateTimefield ), DATENAME(mm, dateTimefield ) WITH ROLLUP )A
 WHERE ( [DATEPART] IS NOT NULL OR QQ IS NOT NULL )

让我知道这是否是你要找的..

于 2013-06-13T15:24:05.893 回答