postgresql - 如何在同一张表的 GROUP 内执行 LIMIT?

标签 postgresql group-by lateral

虽然我在这里阅读了所有类似的问题,但我不知道如何在组内进行限制。阅读 PSQL 文档也没有帮助 :( 考虑以下内容:

CREATE TABLE article_relationship
(
    article_from INT NOT NULL,
    article_to INT NOT NULL,
    score INT
);

我想获得按分数排序的每个给定文章 ID 的前 5 篇相关文章的列表。

这是我尝试过的:

select DISTINCT o.article_from
from article_relationship o
join lateral (
       select i.article_from, i.article_to, i.score from article_relationship i
       order by score desc
       limit 5
       ) p on p.article_from = o.article_from
where o.article_from IN (18329382, 61913904, 66538293, 66540477, 66496909)
order by o.article_from;

它什么也不返回。我的印象是外部查询就像循环,所以我想我只需要那里的源 ID。

另外,如果我想加入包含 idtitle 列的 articles 表并在结果集中获取相关文章的标题怎么办?

我在内部查询中添加了连接:

select o.id, p.*
from articles o
join lateral (
       select a.title, i.article_from, i.article_to, i.score
       from article_relationship i
       INNER JOIN articles a on a.id = i.article_to
       where i.article_from = o.id
       order by score desc
       limit 5
       ) p on true
where o.id IN (18329382, 61913904, 66538293, 66540477, 66496909)
order by o.id;

但这让它变得非常非常慢。

最佳答案

没有行从您的查询返回的问题是您的连接条件是错误的:ON p.article_from = o.article_from;这显然应该是 ON p.article_from = o.article_to

撇开这个问题不谈,您的查询不会返回每个文章 ID 的前 5 个得分关系;相反,它会返回引用整个表中评分最高的 5 篇引用文章之一的文章 ID,以及(还)您指定 ID 的 5 篇引用文章中的至少一篇。

您可以获得每篇引用文章评分最高的 5 篇引用文章,并使用窗口函数对子选择中的分数进行排名,然后在主查询中仅选择前 5 篇。有效地指定引用文章 ID 列表意味着您将对每篇引用文章的这些引用文章的评分方式进行排名:

SELECT article_from, article_to, score
FROM (
    SELECT article_from, article_to, score, 
           rank() OVER (PARTITION BY article_from ORDER BY score DESC) AS rnk
    FROM article_relationship
    WHERE article_to IN (18329382, 61913904, 66538293, 66540477, 66496909) ) a
WHERE rnk < 6
ORDER BY article_from, score DESC;

这与您的代码不同,它为每个 article_from 返回最多 5 条记录,但它与您的初始描述一致。

从表 articles 添加列在主查询中很容易完成:

SELECT a.article_from, a.article_to, a.score, articles.*
FROM (
    SELECT article_from, article_to, score, 
           rank() OVER (PARTITION BY article_from ORDER BY score DESC) AS rnk
    FROM article_relationship
    WHERE article_to IN (18329382, 61913904, 66538293, 66540477, 66496909) ) a
JOIN articles ON articles.id = a.article_to
WHERE a.rnk < 6
ORDER BY a.article_from, a.score DESC;

关于postgresql - 如何在同一张表的 GROUP 内执行 LIMIT?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41274354/

相关文章:

sql - 如何对具有多个条目的一列使用分组依据?

postgresql - Puppet 和 Postgres 烦人的警告:不推荐将 "version"传递给 postgresql::server

postgresql - 具有复合主键的表中记录的顺序是什么

java - Postgis - 如何通过 JDBC 使用数据类型 'geography'

mysql - SQL "group by"仅返回第一行 - 之二

sql - MySQL选择使用日期时间,仅按日期分组

sql - 升级到 PostgreSQL 11 : set-returning functions are not allowed in CASE

sql - postgresql工作时间简化查询

sql - Postgres 中的 GROUP BY - JSON 数据类型不相等?

postgresql - pgadmin 更新后无法登录