SQL Server-更新ステートメントでウィンドウ関数が許可されないのはなぜですか?


10

以下のようなupdateステートメントを実行すると、エラーメッセージが表示され、

ウィンドウ関数は、SELECT句またはORDER BY句でのみ使用できます。

UPDATE dbo.Dim_Chart_of_Account
SET Account_Order = LAG([Account_Order]) OVER (ORDER BY [Account_SKey])

これは、以下のような更新可能なcteを使用して簡単に回避できることを知っています

 WITH my_cte AS (
     SELECT [Account_Order], LAG([Account_Order]) OVER (ORDER BY [Account_SKey]) AS acc_order_lag
     FROM Dim_Chart_of_Account
)
UPDATE my_cte
SET [Account_Order] = acc_order_lag

私の質問は、これがupdateステートメントで許可されていない理由はありますか?回避策として更新可能なcteを使用しないようにすべきですか?

私の懸念は、更新ステートメントでウィンドウ関数を使用するときに問題があるため、これが許容できる方法であるのか、それとも避けるべきなのかを理解したいのです。


1
更新可能なCTEは許容範囲内で問題ありません。なぜそれがUPDATEで許可されていないのか分かりません。
ypercubeᵀᴹ

2
たぶんHallowe'en保護のようなものでしょうか?
アーロンバートランド

回答:


5

UPDATEはSELECTまたはORDER BYと互換性がないため、UPDATE関数ではウィンドウ関数を使用できません。

ウィンドウ関数は、関連する行を再検査し、PARTITION BYやORDER BYなどの条件を適用するスコープ付きSELECTステートメントに似ています。さらに、多くのウィンドウ関数にはORDER BY句が必要です(ROW_NUMBER、LAG、FIRST_VALUEなど)。

UPDATEステートメントはSELECTの代わりにSETを使用するため、SELECTは同じクエリレベルのどこにも許可されません。UPDATEで現れるSELECTはすべてサブクエリに含まれている必要があります。

ORDER BYを禁止することは、UPDATEステートメントが行を更新する順序に影響されないことを考慮すると意味があります。

ウィンドウ関数を使用するためのUPDATEを取得するための回避策としてCTEまたはその他のサブクエリを使用することに固有の欠点はありません。これは、Itzik Ben-GanのようなT-SQLの専門家が提唱する一般的な手法です。(彼の本のMicrosoft SQL Server 2012 High-Performance T-SQL Using Window Functionsを参照して、この正確なシナリオをカバーしています。)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.