Sql-Server

避免重複的 CASE 表達式

  • October 14, 2021
SELECT x, y, z,
CASE
WHEN COUNT (PH.header_id) OVER (PARTITION BY PL.header_id)
   NOT IN (null,0) THEN L_Count
ELSE COUNT (PH.header_id) OVER (PARTITION BY PL.header_id)
END as quantity

有沒有更有效的方法來寫這個?

我非常清楚它在一張大桌子上執行兩次計數。

不幸的是,我無法發布查詢計劃,因為我正在使用的使用者帳戶正在等待 SHOWPLAN 權限。

NOT IN 子句是一個附帶問題。感謝您對改進方法的評論回饋,但問題的重點是重複計數。

這裡有兩個問題:

  • 程式碼是多餘的,因為視窗函式被輸入了兩次
  • 擔心的是 SQL Server 將執行兩次計數,因為它被引用了兩次

首先,我們可以通過只計算該表達式一次來解決整潔方面的問題(我將從NOT IN (NULL, 0)邏輯更改為僅檢查計數是否大於 0(這消除了 NULL 和 0):

;WITH x AS 
(
 SELECT x, y, z, L_Count, 
   q = COUNT (PH.header_id) OVER (PARTITION BY PL.header_id)
 FROM ...something PH and PL...
)
SELECT x, y, z, quantity = CASE WHEN q > 0 THEN L_Count ELSE q END
 FROM x;

這是否是正確最有效的分區選擇是另一回事。

其次,SQL Server 非常聰明,它只在給定範圍內執行一次計算。如上所述,兩次引用一個表達式並不一定意味著它會被計算兩次,並且像我在這個答案中所做的那樣將第二個引用隱藏在 CTE 中也不能保證它只會被計算一次。要確定,您必須檢查執行計劃和其他詳細資訊(如表達式選項卡和由計劃資源管理器提供的性能指標)並進行比較。


擁有表結構、樣本數據和期望的結果(甚至更多的查詢)將真正有助於為您創建更好的(和經過驗證的)解決方案。我只是建議你在你的問題中使用的相同邏輯,我只能假設它現在對你有用(我試圖理解你的CASE邏輯甚至意味著什麼 - 它似乎在說“如果有一個有效的計數來自此視窗函式,然後使用此另一列,但如果此視窗函式沒有有效計數,請使用無效計數")。我懷疑在翻譯/簡化中失去了一些東西。


也可以看看:

引用自:https://dba.stackexchange.com/questions/301074