PostgreSQL - 包括连接表中的所有行

时间:2017-05-18 04:34:00

标签: postgresql join

所以我一直在玩连接,并试图找到实现这一目标的最佳方法。

我们说我有这些表。为简洁起见,并未列出所有列。但是表A的列数比B多了几个。

              Table A
             ---------
| id | member_id | data | updated

然后这个表

              Table B
             ---------
| id | post_id | member_id | post_date

B.post_idTable A.id

的外键

我想连接表A和B但返回所有行。现在我只能让它返回表A中的所有行,只返回表b中匹配的行。我需要在表A中匹配的行表B,然后在2个时间列中最大的ORDER BY DESC。

以下是我一直在玩的问题

SELECT a.*, b.member_id as poster, b.post_date, c.title, c.level 
  FROM tableA as a LEFT JOIN tableC as c ON c.a_id=a.a_id 
   LEFT JOIN tableB as b ON a.id=b.post_id 
    WHERE a.member_id IN (100,101) OR b.member_id IN (100,101) 
     ORDER BY GREATEST(a.updated,b.post_date) DESC LIMIT 10

我没有得到理想的结果。如果我在表A中有一个ID为20的行,那么在表b中匹配了连接,我只从结果中的表b中获取行,而不是从两个表中获取两行。我已经用很多方式玩过,并在SO上尝试了其他答案,只是没有成功。查询应该可以很好地处理许多记录。如果有人有更好,更高性能的方法来做到这一点,并让它工作,请分享。

以下是示例数据:

表A

id   | member_id | data | updated
--- -------   ---------   ---------
10  |   101      | data | 1495081193
11  |   100      | data | 1495081500
12  |   101      | data | 1495081600

表B

id  post_id | member_id | post_date
--- -------   ---------   ---------
2  |   10   | 101      | 1495083000
3  |   10   | 100      | 1495083500

所以我期待的结果是加入

id  post_id | member_id  | data | post_date   | updated
--- -------   ---------   ------  ---------     -------
3  |   10   |   100      | data | 1495083500  | 1495081193
2  |   10   |   101      | data | 1495083000  | 1495081193
12 |        |   101      | data |             | 1495081600
11 |        |   100      | data |             | 1495081500
10 |        |   101      | data |             | 1495081193

但我只是在没有匹配的列是最后一列的情况下得到这个。

id  post_id | member_id  | data | post_date   | updated
--- -------   ---------   ------  ---------     -------
3  |   10   |   100      | data | 1495083500  | 1495081193
2  |   10   |   101      | data | 1495083000  | 1495081193
12 |        |   101      | data |             | 1495081600
11 |        |   100      | data |             | 1495081500

这是粗略示例,请注意我由GREATEST命令使用任一列的时间戳。

1 个答案:

答案 0 :(得分:1)

这是一个非常奇怪的查询结果。毕竟它结合了两个问题:

  • 获取所有A记录
  • 获取所有已加入A数据的B记录

因此查询是联合查询:

selectid b.id, b.post_id, b.member_id, a.data, b.post_date, a.updated
from b
join a on a.id = b.post_id
union all
select id a.id, null, a.member_id, a.data, null, a.updated
from a
order by greatest(updated, coalesce(post_date, updated)) desc;