我有像
这样的数据MyTable的
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
我能想到的唯一方法是使用两个单独的SELECT语句和GROUP BY,然后再使用UNION ALL。有更有效的方法吗?
编辑:我应该说可能有另一个列datavalue2,需要进行平均,而不是求和。不确定这是否有所作为。
答案 0 :(得分: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是here。
在回复您的评论时,grouping sets
是rollup
(和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)
主要的复杂因素是在第一列中打印出正确的值并获得正确的排序。
答案 1 :(得分: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 )
如果您正在寻找,请告诉我。