2012-02-08 31 views
6

簡化SQL語句我有類似下面的查詢:通過CTE

SELECT A.a, A.b, B.c, 
(CASE WHEN ... THEN ... ELSE ... END) AS CalculatedValue, 
B.d 
FROM dbo.TableA A INNER JOIN 
     dbo.TableB B ON (...) 
WHERE (CASE WHEN ... THEN ... ELSE ... END) BETWEEN @DayStart AND @DayEnd 
GROUP BY A.a, (CASE WHEN ... THEN ... ELSE ... END), B.c 

避免重複多次完全相同的表達:(CASE WHEN ... THEN ... ELSE ... END)我想定義使用CTE和查詢這樣的表中選擇,其中,和組由表達CalculatedValue

不幸的是這不起作用,因爲選擇的需求已經包括group by創建CTE

時沒有任何我可以用其他方式不重複CASE WHEN...很多次?

回答

7

使用CROSS APPLY,它可以被用來定義別名字段,然後參考他們:

SELECT A.a, 
     A.b, 
     B.c, 
     CalculatedValue, 
     B.d 
FROM  
     dbo.TableA A 
INNER JOIN 
     dbo.TableB B 
     ON (...) 
CROSS APPLY 
     (SELECT (CASE WHEN ... THEN ... ELSE ... END)) CxA(CalculatedValue) 
WHERE CalculatedValue BETWEEN @DayStart AND @DayEnd 
GROUP BY A.a, CalculatedValue, B.c 

CxA只是一個別名,不管你喜歡,你可以將其命名。

+0

謝謝JNK,這個問題解決了,執行時間相同,但方式比以前更乾淨的代碼,+1和綠色標誌;-) – 2012-02-08 17:15:29

+0

樂意幫忙!我最近才瞭解到這一點,這使得很多事情變得更簡單。 – JNK 2012-02-08 17:16:24

+0

將表格值函數中的公共邏輯封裝起來真的很有趣。查詢最終可能會讀'table CROSS APPLY udf1 CROSS APPLY udf2 CROSS APPLY udf3'和所有'普通'SQL隱藏起來! – MatBailie 2012-02-08 17:39:05

0

對於上述情況,我認爲你可以只做兩層CTE。第一個將爲所有人計算,第二個將從第一個CTE中進行選擇,並根據計算出的值進行過濾。最終的查詢將加入第二層CTE。

只是一個想法。