特定のアイテムの数量(itemid
)と製品の日付コード(proddte
)を合計するこのコードがあります。
select sum(qty), itemid, proddte
from testtable where ....
group by itemid, proddte
私がやりたいのは、itemid/proddte
に関係なく、すべてのqty
の合計を取得することです。私が試してみました:
select sum(qty), itemid, proddte, sum(qty) over() as grandtotal
from testtable
where ....
group by itemid, proddte
ただし、group by
句にはqty
も含める必要があると記載されています。そうした場合、結果は期待した結果とは異なります。
すべての行が同じ値で、個別の列として表される必要はありません。全体の合計を表示できる限り、どのような表現でも受け入れられます。
_CREATE TABLE #foo
(
itemid int,
proddte date,
qty int
);
INSERT #foo(itemid,proddte,qty) VALUES
(1,'20140101',5),(1,'20140102',7),(2,'20150101',10);
-- if it really needs to be a column with the same value
-- in every row, just calculate once and assign it to a variable
DECLARE @sum int = (SELECT SUM(qty) FROM #foo);
SELECT itemid, proddte, GroupedSum = SUM(qty), GrandTotal = @sum
FROM #foo
GROUP BY itemid, proddte;
-- if the grand total can be expressed on its own row,
-- you can use GROUP BY GROUPING SETS:
SELECT itemid, proddte, SUM(qty)
FROM #foo GROUP BY GROUPING SETS((),(itemid,proddte));
-- if that syntax is confusing, you can use a less
-- efficient UNION ALL:
SELECT itemid, proddte, SUM(qty)
FROM #foo GROUP BY itemid,proddte
UNION ALL
SELECT NULL, NULL, SUM(qty)
FROM #foo;
GO
DROP TABLE #foo;
_
_GROUP BY GROUPING SETS
_は基本的に_UNION ALL
_です。 _()
_は、グループ化に関係なくSUM
を取るだけで、リストされている他のグループは個別に集計されます。 GROUP BY GROUPING SETS ((itemid),(itemid,proddte))
を試して、違いを確認してください。
詳細については、ドキュメントを参照してください:
GROUP BYとROLLUP、CUBE、およびGROUPING SETSを併用
Andriyが述べたように、上記のクエリは次のように記述することもできます。
_GROUP BY ROLLUP( (itemid,proddte) )
_
そこにある2つの列は、追加の括弧のペアで囲まれているため、1つの単位になっています。 Andriy デモを書きました Stack Exchange Data Explorerでホストされています。
これも有効な構文です:
_ sum(sum(qty)) over ()
_
最初はそれを見ると少し混乱しますが、ウィンドウが機能していることだけ覚えておく必要があります。 sum() over ()
-_group by
_の後に適用されるため、クエリによるグループの選択リストに表示される可能性のあるすべてのものをウィンドウ集約の内部に配置できます。したがって、(qty
はできますが)sum(qty)
をsum() over ()
内に配置できます。
_select sum(qty), itemid, proddte,
sum(sum(qty)) over () as grandtotal
from testtable
where ....
group by itemid, proddte ;
_
そうは言っても、Aaron Bertrandが提供する_GROUPING SETS
_クエリを使用することをお勧めします。合計をすべての行に表示するのではなく、一度表示する必要があります。
また、合計の合計は合計の計算に使用できますが、合計数が必要な場合は、カウントの合計ではなく合計数を使用する必要があります。
_sum(count(*)) over () as grand_count
_
また、テーブル全体の平均が必要な場合は、さらに複雑になります。
_sum(sum(qty)) over ()
/ sum(count(qty)) over () as grand_average
_
平均の平均がすべての平均と同じではないためです。 (avg(avg(qty)) over ()
を試してみると、上記の総平均とは異なる結果が得られる場合があります。)
回避策の1つは、最初のGROUP BY
を [〜#〜] cte [〜#〜] にラップすることです。
WITH
CTE
AS
(
select
itemid
,proddte
,sum(qty) AS SumQty
from testtable
where ....
group by itemid, proddte
)
SELECT
itemid
,proddte
,SumQty
,SUM(SumQty) OVER () AS grandtotal
FROM CTE
;