2011-10-21 11 views
1

複雑なselect Where句を別のグループに再利用することはできますか?私は何を同じクエリ(条件/場所)で異なるグループ別のグループ

をしています:

(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グループがある場合は特に)@tableまたは#temp表に中間結果を自分でマテリアライズするだろう

+0

ニース..ちょうど入れ替え名/定義:)感謝 – ariel

+2

かどうかわからない@ariel "optimisあなたがあなたの質問で参照するアトオンは、コードまたはパフォーマンスですか?パフォーマンスの最適化として、これの効果は中立になります。クエリー定義は再利用されますが、作業は再利用されません。CTEはまだ2回評価され、計画はおそらく元のクエリと同じになります。 –

+0

はい、実行計画でそれを見た – ariel

2

一つのオプションだけ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)) 

2番目の値は、XをNULLにすることはできません。

参考文献: