SQL获取具有与特定值匹配的最新关联的记录 上下文
我使用PostgreSQL存储SQL获取具有与特定值匹配的最新关联的记录 上下文,sql,postgresql,date,join,greatest-n-per-group,Sql,Postgresql,Date,Join,Greatest N Per Group,我使用PostgreSQL存储文章及其关联的事件。为了示例,下面是两个表的简单结构: 文章表 +----+-----------+-----------------------+ | ID | title | description | +----+-----------+-----------------------+ | 1 | article 1 | article 1 description | | 2 | article 2 | article 2 de
文章
及其关联的事件
。为了示例,下面是两个表的简单结构:
文章表
+----+-----------+-----------------------+
| ID | title | description |
+----+-----------+-----------------------+
| 1 | article 1 | article 1 description |
| 2 | article 2 | article 2 description |
| 3 | article 3 | article 3 description |
| 4 | article 4 | article 4 description |
| 5 | article 5 | article 5 description |
+----+-----------+-----------------------+
+-----+-----------+--------------+----------------+--------------+
| ID | name | eventable_id | eventable_type | created_at |
+-----+-----------+--------------+----------------+--------------+
| 1 | validated | 1 | Article | 2020-05-10 |
| 2 | reported | 1 | Article | 2020-05-11 |
| 3 | reported | 2 | Article | 2020-05-10 |
| 4 | reported | 2 | Article | 2020-05-11 |
| 5 | reported | 2 | Article | 2020-05-12 |
| 6 | reported | 3 | Article | 2020-05-20 |
| 7 | validated | 3 | Article | 2020-05-21 |
| 8 | reported | 4 | Article | 2020-05-12 |
| 9 | moved | 4 | Article | 2020-05-13 |
| 10 | reported | 4 | Article | 2020-05-14 |
| 11 | moved | 5 | Article | 2020-05-13 |
| 12 | moved | 5 | Article | 2020-05-14 |
+-----+-----------+--------------+----------------+--------------+
事件表
+----+-----------+-----------------------+
| ID | title | description |
+----+-----------+-----------------------+
| 1 | article 1 | article 1 description |
| 2 | article 2 | article 2 description |
| 3 | article 3 | article 3 description |
| 4 | article 4 | article 4 description |
| 5 | article 5 | article 5 description |
+----+-----------+-----------------------+
+-----+-----------+--------------+----------------+--------------+
| ID | name | eventable_id | eventable_type | created_at |
+-----+-----------+--------------+----------------+--------------+
| 1 | validated | 1 | Article | 2020-05-10 |
| 2 | reported | 1 | Article | 2020-05-11 |
| 3 | reported | 2 | Article | 2020-05-10 |
| 4 | reported | 2 | Article | 2020-05-11 |
| 5 | reported | 2 | Article | 2020-05-12 |
| 6 | reported | 3 | Article | 2020-05-20 |
| 7 | validated | 3 | Article | 2020-05-21 |
| 8 | reported | 4 | Article | 2020-05-12 |
| 9 | moved | 4 | Article | 2020-05-13 |
| 10 | reported | 4 | Article | 2020-05-14 |
| 11 | moved | 5 | Article | 2020-05-13 |
| 12 | moved | 5 | Article | 2020-05-14 |
+-----+-----------+--------------+----------------+--------------+
问题
在这里,我需要能够获得所有的文章
,它们的最新事件
正在被报告
例如,根据上述数据,我们只能得到:
:因为它已经第1条
然后验证
报告
:因为它只被第2条
报告过
:因为它已被移动,然后被报告(与第1条相同)第4条
:不应返回,因为其最新事件已验证第3条
:不应返回,因为其最新事件已移动第5条
文章
都报告了事件。但是,如何让最新事件被报告
以下是我迄今为止所做的尝试,但没有成功:
SELECT *
FROM articles a
INNER JOIN (
SELECT *
FROM events
WHERE name = 'reported'
ORDER BY created_at
LIMIT 1
) AS e ON e.moderable_id = a.id AND e.moderable_type = 'Article'
我们目前有:
- 459 892篇文章
事件
您可以使用相关子查询进行筛选:
select a.*
from articles a
where
(
select e.name
from events e
where e.eventable_id = a.id and e.eventable_type = 'Article'
order by created_at desc
limit 1
) = 'reported'
我们也可以用横向连接来表示:
select a.*
from articles a
inner join lateral (
select e.name
from events
where e.eventable_id = a.id and e.eventable_type = 'Article'
order by created_at desc
limit 1
) x on x.status = 'reported'
您尝试过查询了吗?注意:您的事件似乎比文章少?@wildplasser是的,因为并非所有文章都有一个事件。非常感谢您,您的两个示例实际上都在工作(我需要使用更大的数据运行更多测试以确保这一点)。我有一个问题:这些查询中哪一个最快?我们目前有459 891篇
文章
和62 074篇事件
@lkartono:我认为它们有相当多的相似之处(并且可能产生相同的执行计划)。不过,您可能需要根据数据评估性能。事件索引(可事件id、可事件类型、创建时间、名称)
可能会有所帮助。感谢与索引相关的提示,从21秒到118毫秒:)