汇总多表父子关系第2部分的公共列

时间:2014-01-16 01:19:38

标签: sql sql-server

这是Summing common columns of multi table parent-child relation的直接跟进。

表格布局是:

CREATE TABLE [dbo].[a]

[primary_key] [nvarchar](7) NOT NULL

CREATE TABLE [dbo].[b]

[column1] [nvarchar](7) NOT NULL
[column2] [int] NOT NULL
[column3] [int] not null

CREATE TABLE [dbo].[c]

[column1] [nvarchar](7) NOT NULL
[column2] [int] NOT NULL
[column3] [int] not null

CREATE TABLE [dbo].[d]

[column1] [nvarchar](7) NOT NULL
[column2] [int] NOT NULL
[column3] [int] not null

CREATE TABLE [dbo].[DateTable]

[index] [int] NOT NULL
[date] [date] NOT NULL

这大致是设计。我在最后一个查询中有1个父项和3个子项,我使用此sql查询对3行进行求和

SELECT a.primary_key,
b.Sum AS Expr1,
c.Sum AS Expr2, 
d.Sum AS Expr3,
ISNULL(b.Sum, 0) + ISNULL(c.Sum, 0) + ISNULL(d.Sum, 0) as [GrandTotal]
FROM dbo.Agency_Table a
OUTER APPLY (SELECT SUM(ISNULL(b.column2, 0)) [Sum] FROM dbo.b WHERE a.primary_key = b.column1) as b
OUTER APPLY (SELECT SUM(ISNULL(c.column2, 0)) [Sum] FROM dbo.c WHERE a.primary_key = c.column1) as c
OUTER APPLY (SELECT SUM(ISNULL(d.column2, 0)) [Sum] FROM dbo.d WHERE a.primary_key = d.column1 as d

现在我想要实现的是使用b,c和d的第3列,它是一个链接到日期表(E)的int字段。我想按日期分组。这可以通过对int进行分组来完成,但最好是按实际日期分组。如此有效地将数据库想象成一个与之无关的妈妈和爸爸表,然后是3个孩子。

我想象的是这样的

SELECT a.primary_key,
b.Sum AS Expr1,
c.Sum AS Expr2, 
d.Sum AS Expr3,
dbo.dateTable.Date 
ISNULL(b.Sum, 0) + ISNULL(c.Sum, 0) + ISNULL(d.Sum, 0) as [GrandTotal]
FROM dbo.Agency_Table a
OUTER APPLY (SELECT SUM(ISNULL(b.column2, 0)) [Sum] FROM dbo.b WHERE a.primary_key = b.column1) as b
OUTER APPLY (SELECT SUM(ISNULL(c.column2, 0)) [Sum] FROM dbo.c WHERE a.primary_key = c.column1) as c
OUTER APPLY (SELECT SUM(ISNULL(d.column2, 0)) [Sum] FROM dbo.d WHERE a.primary_key = d.column1 as d

//some kind of join to the next table
INNER JOIN dbo.b ON dbo.Date.index = dbo.b.Column3 
INNER JOIN dbo.c ON dbo.Date.index = dbo.c.column3  
INNER JOIN dbo.d ON dbo.Date.index = dbo.d.column3


group by dbo.dateTable.Date?

提前抱歉,我觉得我要让你做我的工作。

这适用于sql server 2012。

2 个答案:

答案 0 :(得分:0)

我发现通过更改where子句以在日期中包含过滤器,它确实允许我灵活地对它们进行分组

答案 1 :(得分:0)

您可以将bcd与UNION运算符结合使用,添加一个标识源表的列:

SELECT column1, column2, column3, 1 AS Src FROM dbo.b
UNION ALL
SELECT column1, column2, column3, 2 AS Src FROM dbo.c
UNION ALL
SELECT column1, column2, column3, 3 AS Src FROM dbo.d

...将组合集合加入Date的相关子集:

  (
    SELECT column1, column2, column3, 1 AS Src FROM dbo.b
    UNION ALL
    SELECT column1, column2, column3, 2 AS Src FROM dbo.c
    UNION ALL
    SELECT column1, column2, column3, 3 AS Src FROM dbo.d
  ) AS s
INNER JOIN
  dbo.Dates AS d ON s.column3 = d.DateRef AND d.DateValue = ...

...然后将结果外部加入a

  (
    SELECT column1, column2, column3, 1 AS Src FROM dbo.b
    UNION ALL
    SELECT column1, column2, column3, 2 AS Src FROM dbo.c
    UNION ALL
    SELECT column1, column2, column3, 3 AS Src FROM dbo.d
  ) AS s
INNER JOIN
  dbo.Dates AS d ON s.column3 = d.DateRef AND d.DateValue = ...
RIGHT JOIN
  dbo.a AS a ON s.column1 = a.primary_key

现在您可以按a.primary_key分组,并且为了获得每个子表的单独聚合结果,您可以使用CASE进行条件聚合:

SELECT
  a.primary_key,
  Expr1      = SUM(CASE s.Src WHEN 1 THEN s.column2),
  Expr2      = SUM(CASE s.Src WHEN 2 THEN s.column2),
  Expr3      = SUM(CASE s.Src WHEN 3 THEN s.column2),
  GrandTotal = SUM(s.column2)
FROM
  (
    SELECT column1, column2, column3, 1 AS Src FROM dbo.b
    UNION ALL
    SELECT column1, column2, column3, 2 AS Src FROM dbo.c
    UNION ALL
    SELECT column1, column2, column3, 3 AS Src FROM dbo.d
  ) AS s
INNER JOIN
  dbo.Dates AS d ON s.column3 = d.DateRef AND d.DateValue = ...
RIGHT JOIN
  dbo.a AS a ON s.column1 = a.primary_key
GROUP BY
  a.primary_key
;