Различные группы по предложению для одного и того же запроса (выберите / где) - PullRequest
1 голос
/ 21 октября 2011

Могу ли я повторно использовать сложное предложение 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)

Как я могу это выбрать?

Я использую SQL Server 2008, и это будет входить в функцию, но может быть хранимой процедурой.

Ответы [ 4 ]

5 голосов
/ 21 октября 2011
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 были созданы для подобных ситуаций.

2 голосов
/ 21 октября 2011

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 <i>your complex joins and filters</i>
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 <i>your complex joins and filters</i>
GROUP BY GROUPING SETS ( (X), (Y) )

Второй предполагает, что X не может быть NULL.

Ссылки:

2 голосов
/ 21 октября 2011

Один из вариантов, который вы могли бы оценить (особенно если имеется относительно небольшое количество x,y групп), состоит в том, чтобы самим материализовать промежуточные результаты в таблицу @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 голосов
/ 21 октября 2011

создать вид

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
...