私は長年にわたり、あらゆる種類の集約クエリにGROUP BY
を使用してきました。最近、私は集約を実行するためにPARTITION BY
を使うコードをリバースエンジニアリングしています。私がPARTITION BY
について見つけることができるすべてのドキュメンテーションを読むことにおいて、それはおそらくGROUP BY
のように聞こえます、多分少し追加の機能性が追加された?それらは同じ一般的な機能の2つのバージョンなのか、それともまったく違うのか。
彼らはさまざまな場所で使用されています。 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
は返される行数には影響しませんが、ウィンドウ関数の結果の計算方法は変わります。
簡単な例を挙げることができます
以下の値を持つ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に似ていません。
partition by
は実際にはデータをロールアップしません。それはあなたがグループごとに何かをリセットすることを可能にします。たとえば、グループ化フィールドでパーティション化し、そのグループ内の行に対してrownum()
を使用すると、グループ内の序数列を取得できます。これにより、各グループの先頭でリセットされるID列のように振る舞うことができます。
PARTITION BY結果セットをパーティションに分割します。窓関数は各区画に別々に適用され、計算は区画ごとに再開する。
このリンクで見つかりました: OVER句
ロールアップせずにロールアップされたデータを提供します
つまり、販売地域の相対位置を返したいとします。
PARTITION BYを使用して、同じ行のすべての販売地域にわたる特定の地域の販売額 および MAXの金額を返すことができます。
これは、データを繰り返す必要があることを意味しますが、GROUP BYの場合と同様に、データは集計されてもデータが失われていないという意味で、エンドコンシューマに適している可能性があります。
PARTITION BY
は分析的ですが、GROUP BY
は集約的です。 PARTITION BY
を使用するには、 OVER句 でそれを含める必要があります。
私の理解したところでは、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 を参照してください。
本当に異なる使用シナリオがあります。 GROUP BYを使用すると、同じ列のレコードの一部がマージされ、結果セットの集計ができます。
ただし、PARTITION BYを使用する場合、結果セットは同じですが、ウィンドウ関数の集計のみがあり、レコードをマージしない場合、レコードのカウントは同じままです。
違いを説明する集会に役立つ記事を次に示します。 http://alevryustemov.com/sql/sql-partition-by/
テーブルに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行増加します
小さな観察'group by'を使用して動的にSQLを生成する自動化メカニズムは、 'group by'に関連して実装するのがはるかに簡単です。 'group by'の場合、 'select'列の内容に注意しなければなりません。
私の英語でごめんね。