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 で 2 つの個別の select ステートメントを使用してから、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 setsの一般化です。次のように合計を追加できます。rollupcubegrouping 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 つの個別の GroupBy とは異なり、詳細データを一度だけ通過するため効率的です

 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 に答える