在一个查询中为每篇文章选择文章 + 多条评论
Posted
技术标签:
【中文标题】在一个查询中为每篇文章选择文章 + 多条评论【英文标题】:select articles + multiple comments for each article in one query 【发布时间】:2020-12-20 11:50:17 【问题描述】:我的 postgresql 数据库中有 2 个表。简化后,它们看起来像这样:
// table: articles
+----+-----------+---------------+
| id | title | body |
+----+-----------+---------------+
| 1 | hello | world |
| ... |
+----+-----------+---------------+
// table: comments
+----+-----------+---------------+
| id | articleid | comment |
+----+-----------+---------------+
| 1 | 1 | looks cool! |
| ... |
+----+-----------+---------------+
我想制作一个包含所有文章的概览页面 + 每篇文章的最后 3 个 cmets。这可以通过一个查询来实现吗?
我的查询现在看起来像这样(nodeJS):
let query, values, result;
let ret = [];
// query to select all articles, ordered by ID desc
query = 'SELECT id, title FROM articles ORDER BY id DESC';
result = await postgresql.query(query, []);
// store all rows in a constant
const articles = result.rows;
// loop over each article
articles.forEach(article =>
// fetch the last 3 comments for each article
query = 'SELECT id, comment FROM comments WHERE articleid = $1 ORDER BY id DESC LIMIT 3';
values = [article.id];
result = await postgresql.query(query, values);
// store the comments in a constant
const comments = result.rows;
// push the article information (ID + title) and the comments in the ret array
ret.push(
articleID: article.id,
title: article.title,
comments: comments
);
);
// ret now contains an array of objects of articles + comments
return ret;
我想知道是否可以将两个查询合并为 1,或(如果不可能),这是执行此操作的最佳性能方式。
请注意,这两个表都比我在此处描述的简化版本要大。目前我有 + 1,700 篇文章和 +100,000 个 cmets。
【问题讨论】:
【参考方案1】:一个选项使用横向连接:
select a.id, a.title, c.id, c.comment
from articles a
cross join lateral (
select c.*
from comments c
where c.articleid = a.id
order by id desc
limit 3
) c
order by a.id desc, c.id desc
【讨论】:
【参考方案2】:我相信,一个简单的:
select id, comment from
(select a.id, c.comment, dense_rank() over PARTITION BY a.id ORDER BY c.id DESC) as rn from articles a join comments c on a.id = c.article_id) t
where t.rn <= 3;
所以是的,你只需要使用“DENSE_RANK()”函数https://www.postgresqltutorial.com/postgresql-dense_rank-function/
【讨论】:
谢谢。我去看看。 这里rank()
、dense_rank()
和row_number()
将在输出方面做同样的事情,但row_number()
在性能方面会比其他人更好以上是关于在一个查询中为每篇文章选择文章 + 多条评论的主要内容,如果未能解决你的问题,请参考以下文章