SQL Server 2008r2 Union All Group By

时间:2014-02-16 12:34:34

标签: sql sql-server-2008

我有以下查询:

  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组。我理解为什么,但我无法弄清楚如何解决。 任何人都可以帮忙吗?

3 个答案:

答案 0 :(得分:2)

尝试类似:

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

答案 1 :(得分: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];

这是否比预先聚合,执行联合以及再次聚合更好地取决于许多因素。但是,这确实将聚合和过滤的逻辑放在一个地方。这意味着更容易更改和维护查询而不会出错。

注意我还更改了列名的转义字符。单引号只能用于字符串和日期常量。将它们用于标识符(列别名)可能会导致查询中出现难以检测的错误。

答案 2 :(得分: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]