2014-02-16 5 views
2

У меня есть следующий запрос:SQL Server 2008R2 Union All Group By

SELECT SUM (T0.[TotalSumSy]) AS 'Line Sterling', 
     T0.[WhsCode] AS 'Business Unit' 
    FROM [dbo].[INV1] T0 
     INNER JOIN [dbo].[OINV] T1 
        ON T1.[DocEntry] = T0.[DocEntry] 
    WHERE T1.[DocDate] > (CONVERT(DATETIME, '20121001', 112)) 
GROUP BY T0.[WhsCode] 

UNION ALL 

    SELECT SUM (T0.[TotalSumSy] * -1) AS 'Line Sterling', 
     T0.[WhsCode] AS 'Business Unit' 
    FROM [dbo].[RIN1] T0 
     INNER JOIN [dbo].[ORIN] T1 
        ON T1.[DocEntry] = T0.[DocEntry] 
    WHERE T1.[DocDate] > (CONVERT(DATETIME, '20121001', 112)) 
GROUP BY T0.[WhsCode] 

Однако это возвращение 2 набора групп. Я понимаю, почему, но я не могу понять, как решить. Может ли кто-нибудь помочь?

ответ

2

Существует еще один вариант для выполнения этого запроса, который должен сделать агрегацию только один раз.

select sum("Line Sterling") as [Line Sterling], [Business Unit] 
from ((SELECT T0.[TotalSumSy] AS [Line Sterling], T0.[WhsCode] AS [Business Unit], t1.DocDate 
     FROM [dbo].[INV1] T0 INNER JOIN 
      [dbo].[OINV] T1 
      ON T1.[DocEntry] = T0.[DocEntry] 
    ) union all 
     (SELECT T0.[TotalSumSy] * -1, T0.[WhsCode], t1.DocDate 
     FROM [dbo].[RIN1] T0 INNER JOIN 
      [dbo].[ORIN] T1 
      ON T1.[DocEntry] = T0.[DocEntry] 
    ) 
    ) t 
where [DocDate] > CONVERT(DATETIME, '20121001', 112) 
group by [Business Unit]; 

Выполняется ли это лучше, чем предварительная агрегация, выполнение объединения, а агрегация снова зависит от многих факторов. Однако это ставит логику агрегации и фильтрации в одном месте. Это означает, что легче изменить и поддерживать запрос, не допуская ошибки.

Примечание. Я также изменил escape-символы для имен столбцов. Одиночные кавычки должны использоваться только для констант строки и даты. Использование их для идентификаторов (псевдонимы столбцов) может привести к затруднительным обнаружению ошибок в запросе.

+0

Спасибо. Я нахожу, что ваш запрос легче понять. Однако у меня есть следующая ошибка. Msg 8120, уровень 16, состояние 1, строка 7 Столбец «dbo.RIN1.WhsCode» недопустим в списке выбора, потому что он не содержится ни в агрегатной функции, ни в предложении GROUP BY. – user2694771

+0

@ пользователь2694771. , , Я оставил 'sum()' во втором подзапросе, который превратил его в агрегацию. Это исправлено. –

2

Try что-то вроде:

select sum([TotalSumSy]), WhsCode AS 'Business Unit' from 
(
    SELECT TotalSumSy, T0.[WhsCode] 
    FROM [dbo].[RIN1] T0 INNER JOIN [dbo].[ORIN] T1 ON T1.[DocEntry] = T0.[DocEntry] 
    WHERE T1.[DocDate] > (CONVERT(DATETIME, '20121001', 112)) 

    UNION ALL 

    SELECT 
    T0.[TotalSumSy]*-1, 
    T0.[WhsCode] 
    FROM [dbo].[INV1] T0 INNER JOIN [dbo].[OINV] T1 ON T1.[DocEntry] = T0.[DocEntry] 
    WHERE T1.[DocDate] > (CONVERT(DATETIME, '20121001', 112)) 
) x 
group by WhsCode 
+0

спасибо. Первый select должен дать мне + Value и второй -Values, поскольку они являются кредитами. Сумма всегда будет + значениями (1-й выбор - 2-й выбор). Однако результаты показывают все -Values ​​ – user2694771

0

Я предлагаю создать вид в первую очередь. Затем примените предложение Group by на этом представлении.

create view v1 as (
SELECT 
T0.[TotalSumSy] AS 'Line Sterling', 
T0.[WhsCode] AS 'Business Unit' 
FROM [dbo].[INV1] T0 INNER JOIN [dbo].[OINV] T1 ON T1.[DocEntry] = T0.[DocEntry] 
WHERE T1.[DocDate] > (CONVERT(DATETIME, '20121001', 112)) 

UNION ALL 

SELECT 
T0.[TotalSumSy] * -1 AS 'Line Sterling', 
T0.[WhsCode] AS 'Business Unit' 
FROM [dbo].[RIN1] T0 INNER JOIN [dbo].[ORIN] T1 ON T1.[DocEntry] = T0.[DocEntry] 
WHERE T1.[DocDate] > (CONVERT(DATETIME, '20121001', 112)) 
) 

Затем нанесите Группировать по:

SELECT 
SUM (Line Sterling) AS 'Line Sterling', [Business Unit] 
FROM v1 
GROUP BY [Business Unit] 
+2

Нет необходимости в просмотре. Создание представления только для одного запроса - не очень хорошая идея. – usr