简体   繁体   中英

SQL Server 2008r2 Union All Group By

I have the following query:

  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]

However this is returning 2 sets of groups. I understand why, but I can't figure out how to resolve. Can any one help?

Try something like :

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

There is another option for doing this query, which is to do the aggregation only once.

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];

Whether this performs better than pre-aggregating, doing the union, and aggregating again depends on many factors. However, this does put the logic for the aggregation and the filtering in one place. That means that it is easier to alter and maintain the query without making a mistake.

Note I also changed the escape characters for the column names. Single quotes should only be used for string and date constants. Using them for identifiers (column aliases) can lead to difficult-to-detect errors in the query.

I suggest to create a view in the first place. Then apply the Group by clause on that view.

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

Then apply the Group by:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM