Javascript 在一个查询中为每篇文章选择文章+多个注释

Javascript 在一个查询中为每篇文章选择文章+多个注释,javascript,sql,node.js,postgresql,greatest-n-per-group,Javascript,Sql,Node.js,Postgresql,Greatest N Per Group,我的postgresql数据库中有两个表。简化后,它们看起来像这样: // table: articles +----+-----------+---------------+ | id | title | body | +----+-----------+---------------+ | 1 | hello | world | | ... | +----+-----------+---

我的postgresql数据库中有两个表。简化后,它们看起来像这样:

// table: articles
+----+-----------+---------------+
| id | title     | body          |
+----+-----------+---------------+
| 1  | hello     | world         |
| ...                            |
+----+-----------+---------------+

// table: comments
+----+-----------+---------------+
| id | articleid | comment       |
+----+-----------+---------------+
| 1  | 1         | looks cool!   |
| ...                            |
+----+-----------+---------------+
我想做一个概述页面,包含所有文章+每篇文章的最后3条评论。通过一个查询就可以做到这一点吗

我的查询现在看起来像这样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,或者如果不可能,最好的方法是这样做

请注意,这两个表都比我在这里描述的简化版本大。目前我有+1700篇文章和+100000条评论。

我相信,一个简单的:

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;
是的,你只需要使用一个稠密的秩函数,我相信,一个简单的:

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;

因此,是的,您只需使用密集秩函数,一个选项使用横向连接:

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

一个选项使用横向连接:

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

非常感谢。我来看看。这里的秩、密秩和行数对输出的作用相同,但行数在性能上优于其他行数,谢谢。我来看看,这里的秩、密秩和行数对输出的影响是一样的,但行数在性能上要比其他的好