【问题标题】:postgres, how to select where-in and limit N per foreign key?postgres,如何选择每个外键的位置和限制 N?
【发布时间】:2022-01-27 14:37:23
【问题描述】:

在我的 postgres 数据库中,我有一个帖子和 cmets 表:

帖子:

id  title
1   post1
2   post2
3   post3

cmets:

id  post_id  content
1   1        a   
2   1        b
3   1        c
4   2        d
5   3        e
6   3        f
7   3        g

如何选择 cmets where post_id in (1,3),但每个 post_id 限制为 2 个,这样我得到:

id  post_id  content
1   1        a   
2   1        b
5   3        e
6   3        f

编辑:对于我的具体情况,我可以通过循环遍历 post_ids 数组以编程方式构造查询。

在想:

(select * from comments where post_id = 1 limit 2)
union all
(select * from comments where post_id = 3 limit 2)

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    使用ROW_NUMBER:

    WITH cte AS (
        SELECT *, ROW_NUMBER() OVER (PARTITION BY post_id ORDER BY content) rn
        FROM comments
        WHERE post_id IN (1, 3)
    )
    
    SELECT id, post_id, content
    FROM cte
    WHERE rn <= 2;
    

    【讨论】:

      【解决方案2】:

      您可以使用横向连接。

      select foo.* from 
      posts 
      cross join lateral 
      (select * from comments where post_id=posts.id order by content limit 2) foo 
      where post_id IN (1, 3);
      

      在您的问题中,不清楚要订购什么,所以我只是从蒂姆的回答中复制了订单。这有可能比 row_number() 快得多,因为它会对每个相关帖子的所有 cmets 进行编号,然后过滤掉具有高数字的那些。虽然横向每个帖子只数到 2,然后停止。

      【讨论】:

      • 我在原始问题中添加了一个缺失的细节——我能够以编程方式构建查询。 union all 会是最快的方式吗?
      • 如果您只选择 cmets 表中的列,那么您的 union all 会更快,因为没有连接。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-23
      • 2013-06-25
      • 1970-01-01
      • 2021-07-03
      • 2012-06-02
      • 1970-01-01
      • 2017-06-15
      相关资源
      最近更新 更多