web-dev-qa-db-ja.com

SQL Server:PARTITION BYとGROUP BYの違い

私は長年にわたり、あらゆる種類の集約クエリにGROUP BYを使用してきました。最近、私は集約を実行するためにPARTITION BYを使うコードをリバースエンジニアリングしています。私がPARTITION BYについて見つけることができるすべてのドキュメンテーションを読むことにおいて、それはおそらくGROUP BYのように聞こえます、多分少し追加の機能性が追加された?それらは同じ一般的な機能の2つのバージョンなのか、それともまったく違うのか。

310
Mike Mooney

彼らはさまざまな場所で使用されています。 group byは、以下のようにクエリ全体を変更します。

select customerId, count(*) as orderCount
from Orders
group by customerId

しかし、partition byは/ row_numberのように ウィンドウ関数 に対してのみ動作します。

select row_number() over (partition by customerId order by orderId)
    as OrderNumberForThisCustomer
from Orders

group byは通常、ロールアップして各行の平均または合計を計算することによって返される行数を減らします。 partition byは返される行数には影響しませんが、ウィンドウ関数の結果の計算方法は変わります。

376
Andomar

簡単な例を挙げることができます

以下の値を持つTableAという名前のテーブルがあります。

id  firstname                   lastname                    Mark
-------------------------------------------------------------------
1   arun                        prasanth                    40
2   ann                         antony                      45
3   sruthy                      abc                         41
6   new                         abc                         47
1   arun                        prasanth                    45
1   arun                        prasanth                    49
2   ann                         antony                      49

グループ化

SQL GROUP BY句をSELECTステートメントで使用して、複数のレコードにまたがってデータを収集し、その結果を1つ以上の列でグループ化することができます。

より簡単に言うと、GROUP BYステートメントは集約関数と一緒に使用されて、結果セットを1つ以上の列でグループ化します。

構文:

SELECT expression1, expression2, ... expression_n, 
       aggregate_function (aggregate_expression)
FROM tables
WHERE conditions
GROUP BY expression1, expression2, ... expression_n;

GroupByをテーブルに適用できます

select SUM(Mark)marksum,firstname from TableA
group by id,firstName

結果 :

marksum  firstname
----------------
94      ann                      
134     arun                     
47      new                      
41      sruthy   

実際のテーブルには7行あり、idでグループを適用すると、サーバーはidに基づいて結果をグループ化します。

簡単な言葉で

ここでgroup byは通常、それらをロールアップして各行のSumを計算することによって返される行数を減らします。

によるパーティション分割

でパーティション分割する前に

oVER句を見てみましょう

MSDNの定義に従って

OVER句は、問合せ結果セット内のウィンドウまたはユーザー指定の行セットを定義します。次に、ウィンドウ関数はウィンドウ内の各行の値を計算します。 OVER句を関数と共に使用して、移動平均、累積集計、積算合計、またはグループごとの上位Nの結果などの集計値を計算できます。

partition byは返される行数を減らしません

この例の表では、パーティションを適用できます。

select SUM(Mark) OVER (PARTITION BY id) AS marksum, firstname from TableA

結果:

marksum firstname 
-------------------
134     arun                     
134     arun                     
134     arun                     
94      ann                      
94      ann                      
41      sruthy                   
47      new  

結果を見ると、行が分割され、すべての行がgroup byに似ていません。

206

partition byは実際にはデータをロールアップしません。それはあなたがグループごとに何かをリセットすることを可能にします。たとえば、グループ化フィールドでパーティション化し、そのグループ内の行に対してrownum()を使用すると、グループ内の序数列を取得できます。これにより、各グループの先頭でリセットされるID列のように振る舞うことができます。

PARTITION BY結果セットをパーティションに分割します。窓関数は各区画に別々に適用され、計算は区画ごとに再開する。

このリンクで見つかりました: OVER句

38

ロールアップせずにロールアップされたデータを提供します

つまり、販売地域の相対位置を返したいとします。

PARTITION BYを使用して、同じ行のすべての販売地域にわたる特定の地域の販売額 および MAXの金額を返すことができます。

これは、データを繰り返す必要があることを意味しますが、GROUP BYの場合と同様に、データは集計されてもデータが失われていないという意味で、エンドコンシューマに適している可能性があります。

29
adolf garlic

PARTITION BYは分析的ですが、GROUP BYは集約的です。 PARTITION BYを使用するには、 OVER句 でそれを含める必要があります。

24
OMG Ponies

私の理解したところでは、Partition ByはGroup Byとほとんど同じですが、以下の違いがあります。

そのグループは、実際にはグループごとに1行を返す結果セットをグループ化します。そのため、SQL Serverでは、group by句の一部である集計関数または列のみをSELECTリストに含めることができます。各グループの結果)。

たとえば、Group By句で定義されていないカラムをSELECTリストに含めることを許可するMySQLを考えてみましょう。その場合、グループごとに1行が返されますが、カラムに一意の結果がない場合、保証はありません。何が出力されるでしょう!

ただし、Partition Byを使用すると、関数の結果はGroup Byを使用する集約関数の結果と同じになりますが、それでも通常の結果セットが得られます。つまり、基礎となる行ごとに1行ずつ取得します。このため、SELECTリストのグループごとに一意ではない列を含めることができます。

要約すると、Group Byは、グループごとに1行の出力が必要な場合に最適であり、Partition Byは、すべての行が必要だがグループに基づく集計関数が必要な場合に最適です。

もちろんパフォーマンスの問題もあるかもしれません、 http://social.msdn.Microsoft.com/Forums/ms-MY/transactsql/thread/0b20c2b5-1607-40bc-b7a7-0c60a2a55fba を参照してください。

20
yoel halb

本当に異なる使用シナリオがあります。 GROUP BYを使用すると、同じ列のレコードの一部がマージされ、結果セットの集計ができます。

ただし、PARTITION BYを使用する場合、結果セットは同じですが、ウィンドウ関数の集計のみがあり、レコードをマージしない場合、レコードのカウントは同じままです。

違いを説明する集会に役立つ記事を次に示します。 http://alevryustemov.com/sql/sql-partition-by/

0
Alev Ryustemov

テーブルにname列のレコードが14個あるとします。

group by

select name,count(*) as totalcount from person where name='Please fill out' group BY name;

それは単一行でカウントを与えますすなわち14

しかしpartition by

select row_number() over (partition by name) as total from person where name = 'Please fill out';

14行増加します

0
Ambrish Rajput

小さな観察'group by'を使用して動的にSQLを生成する自動化メカニズムは、 'group by'に関連して実装するのがはるかに簡単です。 'group by'の場合、 'select'列の内容に注意しなければなりません。

私の英語でごめんね。

0
user1785960