pgSQL:两列上的完全外连接省略了行

时间:2016-08-05 22:27:43

标签: postgresql group-by full-outer-join

一些背景知识,我在pgSQL9.5中创建一个表来计算用户执行的操作量,并使用date_trunc()按月对这些操作进行分组。每个单独操作的计数按照以下格式划分为单独的表:

Feedback_Table:                              Comments_Table:
id  |  month  |  feedback_counted            id  |  month  |  comments_counted
----+---------+-------------------           ----+---------+-------------------
 1  |    2    |         3                     1  |    4    |         12
 1  |    3    |        10                     1  |    5    |          4
 1  |    4    |         7                     1  |    6    |         57
 1  |    5    |         2                     1  |    7    |         12

理想情况下,我想在" id"上对这些表进行全面的联接。和"月"列同时生成此查询:

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的新手,我不知道如何解决这个问题,我们将不胜感激。

2 个答案:

答案 0 :(得分:0)

而不是ON c.id = f.id AND c.month = f.month

SELECT c.id, c.month, feedback_counted, comments_counted
FROM comments c 
FULL OUTER JOIN feedback f 
ON c.id = f.id AND c.month = f.month;

 id | month | feedback_counted | comments_counted 
----+-------+------------------+------------------
    |       |                3 |                 
    |       |               10 |                 
  1 |     4 |                7 |               12
  1 |     5 |                2 |                4
  1 |     6 |                  |               57
  1 |     7 |                  |               12
(6 rows)    

使用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)

答案 1 :(得分:0)

USING()ON基本相同,只是如果两个表共享相同的列名,则可以使用USING()代替ON来保存一些输入努力。话虽这么说,使用USING()是行不通的。在Postgresql(不确定其他SQL版本)中,即使使用USING(),您仍然需要指定c.id和c.month。而且,只要您指定列,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;