来自两个表的总和值,分别是GROUP BY和WHERE

时间:2018-11-25 09:38:44

标签: postgresql

我下面有两个表,分别名为sent_tablereceived_table。我正在尝试将它们混在一起以实现output_table。到目前为止,我所有的尝试都导致大量重复项和完全虚假的总和值。

我假设我需要使用GROUP BY和WHERE来实现此目标。我希望能够根据用户名进行过滤。

sent_table

+----+------+-------+----------+
| id | name | value | order_id |
+----+------+-------+----------+
|  1 | dave |   100 |        1 |
|  2 | dave |   200 |        1 |
|  3 | dave |   300 |        2 |
+----+------+-------+----------+

received_table

+----+------+-------+----------+
| id | name | value | order_id |
+----+------+-------+----------+
|  1 | dave |   400 |        1 |
|  2 | dave |   500 |        2 |
|  3 | dave |   600 |        2 |
+----+------+-------+----------+

输出表

+------+----------+----------+
| sent | received | order_id |
+------+----------+----------+
|  300 |      400 |        1 |
|  300 |     1100 |        2 |
+------+----------+----------+

我很不高兴地尝试了以下方法。这不会对我希望如何解决此问题施加任何限制。这就是我试图做到的方式。

SELECT *
FROM
 ( select SUM(value) as sent, order_id FROM sent_table WHERE name='dave' GROUP BY order_id) A
CROSS JOIN 
 ( select SUM(value) as received, order_id FROM received_table WHERE name='dave' GROUP BY order_id) B

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

对每个表求和,按order_id分组,然后将结果相加。要获得即使缺少一侧的行,请执行FULL OUTER JOIN:

SELECT COALESCE(s.order_id, r.order_id) AS order_id, s.sent, r.received
FROM (
  SELECT order_id, SUM(value) AS sent
  FROM sent
  GROUP BY order_id
) s
FULL OUTER JOIN (
  SELECT order_id, SUM(value) AS received
  FROM received
  GROUP BY order_id
) r
USING (order_id)
ORDER BY 1

结果:

| order_id | sent | received |
| -------- | ---- | -------- |
| 1        | 300  | 400      |
| 2        |      | 1100     |

请注意order_id上的COALESCE,因此,如果sent中缺少该字符,则会从recevied中获取,因此该值永远不会为NULL。

如果您想用0代替NULL(例如,当发送或接收的该order_id中没有记录)时,您将执行COALESCE(s.sent, 0) AS sent, COALESCE(r.received, 0) AS received

https://www.db-fiddle.com/f/nq3xYrcys16eUrBRHT6xLL/2