【问题标题】:Summing common columns of multi table parent-child relation对多表父子关系的常用列求和
【发布时间】:2014-01-15 22:00:53
【问题描述】:

我有四个以父子关系构造的表。一个表有一个主键,而其他三个表,否则彼此不相关,将该主键作为外键。也就是说,表 A 有一个称为客户 ID 的主键。表 B、C 和 D 也有客户 ID 和一些其他信息。

我想要实现的是对表 B、C 和 D 的 column2 求和。我已经尝试过:

SELECT dbo.a.primary_key,
       SUM(dbo.b.column2) AS Expr1,
       SUM(dbo.c.column2) AS Expr2, 
       SUM(dbo.d.column2) AS Expr3
FROM   dbo.a 
INNER JOIN dbo.b ON dbo.a.primary_key = dbo.b.column1 
INNER JOIN dbo.c ON dbo.a.primary_key = dbo.c.column1  
INNER JOIN dbo.d ON dbo.a.primary_key = dbo.d.column1
GROUP BY dbo.a.primary_key

这不返回任何内容。我还尝试了一个返回空值的左外连接。我也尝试了下面的行,这是我真正想要实现的:

SUM(dbo.b.column2) + SUM(dbo.c.column2) + SUM(dbo.d.column2) AS Expr1

这可能归结于糟糕的设计,因为我可以有效地将这三个表合并到一个表中,但相信这样会更整洁。

一旦我解决了这个问题,我想将它扩展为表 B、C 和 D 的第 3 列,以便它们有一个日期字段,它是一个 int 并链接回一个日期表 (E)。我想将表 A、B、C 和 D 同时连接到新创建的 E,按日期和 a.primary_key 分组。这可能吗,还是我需要重新考虑设计?

【问题讨论】:

  • 如何将列JOIN dbo.b.column2 加入表中,不应该是表吗?
  • 一旦你解决了这个问题,请为第二部分做一个很好的例子 - 就像你在这里所做的那样......也许是一个新问题!
  • 抱歉错字。我正忙于删除表和列的名称,不小心更改了那个。这仍然没有返回结果
  • 如果将其更改为外连接,是否会返回 primary_key 值,而只是没有总和?
  • 是的,安德鲁,这是正确的

标签: sql sql-server database sql-server-2012


【解决方案1】:

如果您只需要选择一个列,您可以使用 APPLY 而不是 JOIN。
编辑:如果有任何 NULL 值,此查询应该会为您提供 SUM ...
EDIT2:将 CROSS APPLY 更改为 OUTER APPLY,因为如果其中一个 SUMS 不存在,则整个 ROW 将从结果中删除。

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

【讨论】:

  • 这行得通。正如我在上面发布的那样,我认为问题与此有关“好的,我想我已经发现问题出在你们的帮助下。a.primary_key 可能在 b.column1 的一个或多个中不包含值,c.column1 和 d.column1"
  • 这可能是一个新问题,但是如果我想将最高位更改为 b.sum + c.sum + d.sum 这将返回一个空值。我猜我需要以某种方式捕获空值
  • @TSScoder 我发布了一个修改后的查询,该查询也将选择三个 SUM 的总和..
【解决方案2】:

从您的示例中可以清楚地看出,您不小心将列名放入了 JOIN 表名中。

改变

INNER JOIN
dbo.b.column2

INNER JOIN
dbo.b

其他两个也一样。

【讨论】:

  • 抱歉,删除列名时弄错了。这仍然没有返回任何结果。
  • 嗯。您的查询没有什么特别之处。您可以提取一些示例数据并在此处发布吗?理想情况下,将其编写为 CREATE 和 INSERT 语句,以便我们可以重新创建场景。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-13
  • 2018-07-12
  • 1970-01-01
  • 2021-12-07
相关资源
最近更新 更多