两列上的 Full Outer Join 省略了行
Full Outer Join on two columns is omitting rows
一些背景知识,我在 Postgres 9.5 中制作了一个 table,它计算用户执行的操作数并使用 date_trunc() 按月对这些操作进行分组。每个单独操作的计数按照以下格式分为单独的 tables:
Feedback table:
id | month | feedback_counted
----+---------+-------------------
1 | 2 | 3
1 | 3 | 10
1 | 4 | 7
1 | 5 | 2
Comments table:
id | month | comments_counted
----+---------+-------------------
1 | 4 | 12
1 | 5 | 4
1 | 6 | 57
1 | 7 | 12
理想情况下,我想同时在“id”和“month”列上对这些 table 进行 FULL OUTER JOIN 并生成此查询:
Combined table:
id | month | feedback_counted | comments_counted
----+---------+--------------------+-------------------
1 | 2 | 3 |
1 | 3 | 10 |
1 | 4 | 7 | 12
1 | 5 | 2 | 4
1 | 6 | | 57
1 | 7 | | 12
但是,我当前的查询没有捕获反馈日期,显示如下:
Rollup table:
id | month | feedback_counted | comments_counted
----+---------+--------------------+-------------------
| | |
| | |
1 | 4 | 7 | 12
1 | 5 | 2 | 4
1 | 6 | | 57
1 | 7 | | 12
这是我当前的声明,请注意它使用 date_trunc 代替月份。我稍后添加操作计数,主要问题就在这里。
CREATE TABLE rollup_table AS
SELECT c.id, c.date_trunc
FROM comments_counted c FULL OUTER JOIN feedback_counted f
ON c.id = f.id AND c.date_trunc = f.date_trunc
GROUP BY c.id, c.date_trunc, f.id, f.date_trunc;
我是 SQL 的新手,我不确定如何解决这个问题,如有任何帮助,我们将不胜感激。
将ON c.id = f.id AND c.month = f.month
替换为USING(id, month)
。
SELECT id, month, feedback_counted, comments_counted
FROM comments c
FULL OUTER JOIN feedback f
USING(id, month);
id | month | feedback_counted | comments_counted
----+-------+------------------+------------------
1 | 2 | 3 |
1 | 3 | 10 |
1 | 4 | 7 | 12
1 | 5 | 2 | 4
1 | 6 | | 57
1 | 7 | | 12
(6 rows)
中测试
USING()
和ON
基本一样,只是如果2个表的列名相同,可以用USING()
代替ON
保存一些打字工作。也就是说,使用 USING()
是行不通的。在 Postgresql(不确定其他 sql 版本)中,您仍然需要指定 c.id 和 c.month,即使是 USING()
。并且只要您指定了列,Postgresql 将只提取这些列的值所在的行。这就是为什么在完全外连接下会丢失行。
这是一种至少对我有用的方法。
SELECT COALESCE(c.id, f.id) AS id,
COALESCE(c.month, f.month) AS month,
feedback_counted,
comments_counted
FROM comments c
FULL OUTER JOIN feedback f
ON c.id = f.id AND c.month = f.month;
一些背景知识,我在 Postgres 9.5 中制作了一个 table,它计算用户执行的操作数并使用 date_trunc() 按月对这些操作进行分组。每个单独操作的计数按照以下格式分为单独的 tables:
Feedback table:
id | month | feedback_counted
----+---------+-------------------
1 | 2 | 3
1 | 3 | 10
1 | 4 | 7
1 | 5 | 2
Comments table:
id | month | comments_counted
----+---------+-------------------
1 | 4 | 12
1 | 5 | 4
1 | 6 | 57
1 | 7 | 12
理想情况下,我想同时在“id”和“month”列上对这些 table 进行 FULL OUTER JOIN 并生成此查询:
Combined table:
id | month | feedback_counted | comments_counted
----+---------+--------------------+-------------------
1 | 2 | 3 |
1 | 3 | 10 |
1 | 4 | 7 | 12
1 | 5 | 2 | 4
1 | 6 | | 57
1 | 7 | | 12
但是,我当前的查询没有捕获反馈日期,显示如下:
Rollup table:
id | month | feedback_counted | comments_counted
----+---------+--------------------+-------------------
| | |
| | |
1 | 4 | 7 | 12
1 | 5 | 2 | 4
1 | 6 | | 57
1 | 7 | | 12
这是我当前的声明,请注意它使用 date_trunc 代替月份。我稍后添加操作计数,主要问题就在这里。
CREATE TABLE rollup_table AS
SELECT c.id, c.date_trunc
FROM comments_counted c FULL OUTER JOIN feedback_counted f
ON c.id = f.id AND c.date_trunc = f.date_trunc
GROUP BY c.id, c.date_trunc, f.id, f.date_trunc;
我是 SQL 的新手,我不确定如何解决这个问题,如有任何帮助,我们将不胜感激。
将ON c.id = f.id AND c.month = f.month
替换为USING(id, month)
。
SELECT id, month, feedback_counted, comments_counted
FROM comments c
FULL OUTER JOIN feedback f
USING(id, month);
id | month | feedback_counted | comments_counted
----+-------+------------------+------------------
1 | 2 | 3 |
1 | 3 | 10 |
1 | 4 | 7 | 12
1 | 5 | 2 | 4
1 | 6 | | 57
1 | 7 | | 12
(6 rows)
中测试
USING()
和ON
基本一样,只是如果2个表的列名相同,可以用USING()
代替ON
保存一些打字工作。也就是说,使用 USING()
是行不通的。在 Postgresql(不确定其他 sql 版本)中,您仍然需要指定 c.id 和 c.month,即使是 USING()
。并且只要您指定了列,Postgresql 将只提取这些列的值所在的行。这就是为什么在完全外连接下会丢失行。
这是一种至少对我有用的方法。
SELECT COALESCE(c.id, f.id) AS id,
COALESCE(c.month, f.month) AS month,
feedback_counted,
comments_counted
FROM comments c
FULL OUTER JOIN feedback f
ON c.id = f.id AND c.month = f.month;