【问题标题】:PostgreSQL - Include all rows from joined tablesPostgreSQL - 包括连接表中的所有行
【发布时间】:2017-05-18 04:34:00
【问题描述】:

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

假设我有这些表。为简洁起见,没有放置所有列。但是表 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 的行,然后是两个时间列中最大的 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 中获取行,而不是从两个表中获取两行。我玩过很多方法并尝试过其他答案,只是没有解决。查询应该对许多记录执行良好。如果有人有更好和更高性能的方法来做到这一点并使其工作,请分享。

这里是示例数据:

表 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 排序以使用任一列的时间戳。

【问题讨论】:

  • 我不明白。请展示 A、B 的一些示例数据,您得到的结果以及您期望的结果。
  • @ThorstenKettner 我已经更新了问题。

标签: postgresql join


【解决方案1】:

这是一个很奇怪的查询结果。毕竟这是两个查询的组合:

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

因此查询是联合查询:

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;

【讨论】:

  • 这给了我使用 Union 所需的方向,这篇文章和另一篇文章帮助我想出了解决方案。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-10
  • 1970-01-01
  • 2021-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多