web-dev-qa-db-ja.com

「OVER」句の「ORDER BY」引数と「PARTITION BY」引数の違いは何ですか?

以下のクエリはどちらもまったく同じ結果を返しますが、これは引数がどのように機能するかではなく、データセットが原因であると思います。

OVER句を使用する場合、ORDER BYPARTITION BYの違いは何ですか。

少し異なる注意点として、より複雑な響きGROUP BYの代わりにPARTITION BYという用語を使用しないでください。この場合、パーティショニングを使用すると、グループ化と同じ結果が得られるようです。これらの内部パーティションを変更でき、それらの変更がテーブルに反映されることを知っています。それが理由ですか?

クエリ1:

SELECT
    CP.iYear,
    AVG(AVG(CP.mUpgradeCost)) OVER(ORDER BY iYear) AS [avg]
FROM ProForma.dbo.CapitalProject CP
GROUP BY CP.iYear

クエリ2:

SELECT
    CP.iYear,
    AVG(AVG(CP.mUpgradeCost)) OVER(PARTITION BY iYear) AS [avg]
FROM ProForma.dbo.CapitalProject CP
GROUP BY CP.iYear
7
Zach Smith

_PARTITION BY_は「ウィンドウグループ」として機能し、_ORDER BY_はグループ内の順序付けを行います。ただし、_GROUP BY CP.iYear_を使用しているため、ウィンドウを実質的に1行に削減しています(_GROUP BY_が実行されますbeforeウィンドウ関数)。単一の行の平均が、その行の値になります(あなたの場合はAVG(CP.mUpgradeCost))。

クエリ2については、移動平均か何かを作成しようとしていますか?そのクエリが何を返すと予想されるかさえわかりません。

_GROUP BY CP.iYear_を削除してAVG(AVG(...))AVG()に変更すると、違いがわかります。

_PARTITION BY_や_ORDER BY_の使用をうまく説明できる例を次に示します。

ランダムテーブル:

_a     b
----- ------
X     1001
X     1002
X     1003
Y     1001
Y     1002
_

さて、

_SELECT a, b, COUNT(*) OVER (PARTITION BY a) FROM r;
_

戻ります

_a     b
----- ------ ------
X     1001   3
X     1002   3
X     1003   3
Y     1001   2
Y     1002   2
_

したがって、a = Xの行が3行、a = Yの行が2行あることがわかります。 _ORDER BY_句は、行番号や積算合計などのorderedウィンドウ関数が必要な場合に役立ちます。

_SELECT a, b, ROW_NUMBER() OVER (PARTITION BY a ORDER BY b),
             SUM(b) OVER (PARTITION BY a ORDER BY b ROWS UNBOUNDED PRECEDING)
FROM r;
_

... あなたにあげる:

_a     b
----- ------ ------ ------
X     1001   1      1001
X     1002   2      2003
X     1003   3      3006
Y     1001   1      1001   <- row number and running total resets here; new partition
Y     1002   2      2003
_
10