2011-10-21 85 views
1

我可以重複使用一個複雜的條款選擇在哪裏by子句不同的羣體?不同組通過在相同的查詢(選擇/凡)

我在做什麼:

(Select X, Count(*) From [Big where clause with many tables] Group By X) 
Union All 
(Select Y, Count(*) From [Big where clause with many tables] Group By Y) 

我怎樣才能optmise呢?

我使用的是SQL Server 2008中,這將大大函數內部,但可能是一個存儲過程。

回答

5
WITH basequery AS (Select * From [Big where clause with many tables]) 
SELECT X, COUNT(*) FROM basequery GROUP BY X 
UNION ALL 
SELECT Y, COUNT(*) FROM basequery GROUP BY Y; 

CTE是爲這樣的情況而製造的。你可以評估(特別是如果有相對較少的x,y組)

+0

不錯..只是換名/定義:)謝謝 – ariel

+2

@ariel不知道是否「減少昂貴通貨膨脹」你指的是你的問題的代碼或性能?作爲性能優化,這種效應將是中性的。它將重用查詢定義而不是工作。CTE仍會得到兩次評估,該計劃可能與您的原始查詢相同。 –

+0

是的,看到在執行計劃 – ariel

2

一個辦法是給自己物化中間結果爲@table#temp表,則只是從SELECT(一#temp表會更好,因爲你可以設置比下面的更好指標,它允許填充它被並行化,但這些不具備的功能)

DECLARE @T TABLE 
(
X int, 
Y int, 
Cnt int, 
UNIQUE(X,Y,Cnt), /*Cnt just included to make index covering*/ 
UNIQUE(Y,X,Cnt) 
) 

INSERT INTO @T 
Select X, Y, Count(*) 
From [Big where clause with many tables] 
Group By X, Y 


SELECT X, SUM(Cnt) 
FROM @T 
GROUP BY X 
UNION ALL 
SELECT Y, SUM(Cnt) 
FROM @T 
GROUP BY Y 
0

創建視圖的選擇查詢

CREATE VIEW SomeView 
AS 
    Select X, Y, Count(*) AS C From [Big where clause with many tables] 

然後使用視圖:

Select X, C FROM SomeView GROUP BY X 
2

SQL Server 2008中推出了GROUPING SETS()這似乎正是你所追求的。由他人提出的解決方案UNION現在可以輕鬆地與一個單一的選擇來替換GROUPING SETS

基本上,您使用的是這樣的:

SELECT A, B, C 
FROM … 
WHERE … 
GROUP BY GROUPING SETS ((A), (B), (C)) 

這相當於

SELECT A, NULL, NULL, … 
FROM … 
WHERE … 
GROUP BY A 

UNION ALL 

SELECT NULL, B, NULL, … 
FROM … 
WHERE … 
GROUP BY B 

UNION ALL 

SELECT NULL, NULL, C, … 
FROM … 
WHERE … 
GROUP BY C 

所以,您的查詢可能是這樣的:

SELECT X, Y, COUNT(*) 
FROM your complex joins and filters 
GROUP BY GROUPING SETS ((X), (Y)) 

或者這樣:

SELECT 
    CASE WHEN X IS NULL THEN 'Y' ELSE 'X' END AS ObjType 
    CASE WHEN X IS NULL THEN Y ELSE X END AS Obj, 
    COUNT(*) 
FROM your complex joins and filters 
GROUP BY GROUPING SETS ((X), (Y)) 

第二個假定X不能爲NULL。

參考文獻: