web-dev-qa-db-ja.com

SQLクエリ-グループ、グループ合計、総計を表示するように選択する方法

私はいくつかのアドバイスを見ましたが、サブクエリや不要な結合を使用せずにデータテーブルからグループ、グループ合計、総計を選択する最良の方法を知りたいです。

私の最初の考えはこのようなものでした:

select   product_family, 
         sum(widgets), 
         sum(widgets) over ()
from     table.widget
group by product_family

または以下:

select   product_family, 
         sum(widgets), 
         sum(widgets) over (partition by all_field)
from     table.widget
group by product_family

明らかにこれらはどちらも機能しません。パーティションは実際の行/グループよりも高次になる可能性があることを知っていますが、最初の例として空白のままにする以外に、「すべて」でパーティション化する方法はわかりません。ただし、group byステートメントでは機能しません。

私が見つけることができる最高のものは次のようなものです:

select product_family, 
       family_sum, 
       sum(family_sum) over () as grand_sum 
from (
      select   product_family, sum(widgets)
      from     table.widget
      group by product_family
     ) as A

それでもサブクエリが必要ですが、これは問題ありません。ここには簡単な機能がないように感じます。

2
user45867

_GROUP BY ROLLUP_または-さらに良い-_GROUP BY GROUPING SETS_は、総計を含む追加の行が必要な場合に最適です。

すべての行(別の列)の総計が必要な場合は、クエリを少し調整する必要があります。集計関数SUM(widgets)をウィンドウ関数で使用できます。

_select   product_family, 
         sum(widgets)              as total, 
         sum(sum(widgets)) over () as grand_total
from     table.widget
group by product_family ;
_
3
ypercubeᵀᴹ

GROUP BY ROLLUP はあなたが望むことをします。

例として:

SELECT o.schema_id
    , type_desc
    , [Count Of Objects] = COUNT(o.object_id)
FROM sys.objects o
GROUP BY ROLLUP (o.schema_id, o.type_desc)

これにより、次の出力が生成されます。

╔═══════════╦════════════════════════╦════════════ ══════╗
║schema_id║type_desc Objectsオブジェクトの数║
╠═══════════╬═══════════ ═════════════╬══════════════════╣
║1║PRIMARY_KEY_CONSTRAINT║7║
 ║1║SERVICE_QUEUE║3║
║1║USER_TABLE║8║
║1║NULL║18║
║4║INTERNAL_TABLE║16║
║4 ║SYSTEM_TABLE║72║
║4║NULL║88║
║NULL║NULL║106║
╚═══════════╩═══ ═════════════════════╩══════════════════╝

最初の2列に表示されているNULLは、積み上げ金額を表します。

「きれい」にするには、NULLのロールアップされた値のいくつかの置換を使用できます。

SELECT [Schema Name] = CASE 
        WHEN s.name IS NULL THEN 
            '[Grand Total]' 
        ELSE s.name 
        END
    , [Object Type] = CASE 
        WHEN o.type_desc IS NULL THEN 
            '[Total - ' + COALESCE(s.name, 'Overall') + ']' COLLATE SQL_Latin1_General_CP1_CI_AS 
        ELSE o.type_desc 
        END
    , [Count of Objects] = COUNT(o.object_id)
FROM sys.objects o
    INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
GROUP BY ROLLUP (s.name, o.type_desc);
╔═══════════════╦════════════════════════╦════════ ══════════╗
║スキーマ名║オブジェクトタイプ║オブジェクトの数║
╠═══════════════╬═ ═══════════════════════╬══════════════════╣
║dbo ║PRIMARY_KEY_CONSTRAINT║7║
║dbo║SERVICE_QUEUE║3║
║dbo║USER_TABLE║8║
║dbo║[Total-dbo]║18║
 ║sys║INTERNAL_TABLE║16║
║sys║SYSTEM_TABLE║72║
║sys║[合計-sys]║88║
║[総計]║[合計-全体]║106║
╚═══════════════╩════════════════════════ ╩══════════════════╝
5
Max Vernon