问题 从两个表中获取几列的总和


我想从两个不同的表中获得几列的总和(这些表共享相同的结构)。

如果我只考虑一个表,我会写这种查询:

SELECT MONTH_REF, SUM(amount1), SUM(amount2)
    FROM T_FOO
    WHERE seller = XXX
    GROUP BY MONTH_REF;

但是,我还想使用表T_BAR中的数据,然后有一个 select 返回以下列的查询:

  • MONTH_REF
  • SUM(T_FOO.amount1)+ SUM(T_BAR.amount1)
  • SUM(T_FOO.amount2)+ SUM(T_BAR.amount2)

一切按价值分组 MONTH_REF

请注意给定的记录 MONTH_REF 可以在一个表中找到,但不能在另一个表中找到。 在这种情况下,我想得到的总和 T_FOO.amount1 + 0 (要么 0 + T_BAR.amount1)。

如何编写SQL查询以获取此信息?

有关信息,我的数据库是Oracle 10g。


5380
2017-09-07 08:32


起源



答案:


您可以在组之前将表联合起来(顺便说一下,这是在Oracle上):

SELECT t.month_ref, SUM(t.amount1), SUM(t.amount2)
  FROM (SELECT month_ref, amount1, amount2
          FROM T_FOO
         WHERE seller = XXX
         UNION ALL
        SELECT month_ref, amount1, amount2
          FROM T_BAR
         WHERE seller = XXX
         ) t
 GROUP BY t.month_ref

您还可以将表与卖方字段合并,稍后再过滤(如果您需要更高级的逻辑):

 SELECT t.month_ref, SUM(t.amount1), SUM(t.amount2)
   FROM (SELECT month_ref, amount1, amount2, seller
           FROM T_FOO
          UNION ALL
         SELECT month_ref, amount1, amount2, seller
           FROM T_BAR) t
  where t.seller = XXX
  GROUP BY t.month_ref

12
2017-09-07 09:16



最后,我更喜欢你的解决方案(第一个),因为它比列文解决方案更清晰...... - romaintaz
第一个更有效,因为你比移动时更快地减少行数 WHERE 子句之外的子句 SELECT。 - JohnB
谢谢我用了第二个。 - Emmanuel Angelo.R


答案:


您可以在组之前将表联合起来(顺便说一下,这是在Oracle上):

SELECT t.month_ref, SUM(t.amount1), SUM(t.amount2)
  FROM (SELECT month_ref, amount1, amount2
          FROM T_FOO
         WHERE seller = XXX
         UNION ALL
        SELECT month_ref, amount1, amount2
          FROM T_BAR
         WHERE seller = XXX
         ) t
 GROUP BY t.month_ref

您还可以将表与卖方字段合并,稍后再过滤(如果您需要更高级的逻辑):

 SELECT t.month_ref, SUM(t.amount1), SUM(t.amount2)
   FROM (SELECT month_ref, amount1, amount2, seller
           FROM T_FOO
          UNION ALL
         SELECT month_ref, amount1, amount2, seller
           FROM T_BAR) t
  where t.seller = XXX
  GROUP BY t.month_ref

12
2017-09-07 09:16



最后,我更喜欢你的解决方案(第一个),因为它比列文解决方案更清晰...... - romaintaz
第一个更有效,因为你比移动时更快地减少行数 WHERE 子句之外的子句 SELECT。 - JohnB
谢谢我用了第二个。 - Emmanuel Angelo.R


你尝试过使用工会吗?

SELECT MONTH_REF, SUM(amount1), SUM(amount2)
FROM (
  SELECT MONTH_REF, SUM(amount1) AS amount1, SUM(amount2) as amount2
      FROM T_FOO
      WHERE seller = XXX
      GROUP BY MONTH_REF
  UNION ALL SELECT MONTH_REF, SUM(amount1), SUM(amount2)
      FROM T_BAR
      WHERE seller = XXX
      GROUP BY MONTH_REF
  ) tmp
GROUP BY MONTH_REF

2
2017-09-07 08:40



@romaintaz:没问题。有一个问题,您有没有想过不同的解决方案?我认为 分组 - 分组 - 分组 在大型数据集上会比单纯的更快 工会 - 分组 解。 - Lieven Keersmaekers


或者,外连接也应该起作用:

SELECT month_ref, 
       SUM(t_foo.amount1) + SUM(t_bar.amount1), 
       SUM(t_foo.amount2)+SUM(t_bar.amount2)
FROM   t_foo FULL OUTER JOIN t_bar
       ON t_foo.month_ref = t_bar.month_ref
GROUP BY month_ref

1
2017-09-07 08:47



这个查询需要花费太多时间(特别是与Lieven的答案相比),此外它会返回错误的结果。它还需要NVL(SUM(...),0)否则我会得到空值... - romaintaz


我终于使用了这个 利芬的答案。

这是正确的代码(amount1 = ... 没有在我的环境中工作,而且有太多 ; 在查询中):

SELECT MONTH_REF, SUM(sumAmount1), SUM(sumAmount2)
FROM (
  SELECT MONTH_REF, SUM(amount1) as sumAmount1, SUM(amount2) as sumAmount1
      FROM T_FOO
      WHERE seller = XXX
      GROUP BY MONTH_REF
  UNION ALL SELECT MONTH_REF, SUM(amount1), SUM(amount2)
      FROM T_BAR
      WHERE seller = XXX
      GROUP BY MONTH_REF
  ) tmp
GROUP BY MONTH_REF

1
2017-09-07 09:08





SELECT (SELECT SUM(amount) from debit) as debitamounts, (SELECT SUM(amount) from credit) as creditamounts

-1
2017-11-25 16:17



请为您的解决方案添加一些评论,说明解决问题的原因和方法 - Bhavesh Odedra
这个命令不完整.... - taboubim