【问题标题】:Limit a has-many relationship by the parent table限制父表的has-many关系
【发布时间】:2020-08-28 03:41:56
【问题描述】:

使用 Postgres 9.6,user has_many posts,其中帖子可以是 publicprivate。我需要返回加入他们帖子的用户列表其中用户拥有 > 0 个公共帖子,并根据 user 限制返回的记录,同时还限制加入 posts 的数量。

作为一个表示为模拟 ORM 的示例:

// User A has 4 public posts
// User B has 0 public posts
// User C has 1 public post
// User D has 5 public posts

// I am limiting the posts fetched per-user to 3 and the users fetched to 2:

[
  {
    user: "A",
    posts: [
      { id: 10 },
      { id: 28 },
      { id: 33 }
      // Fourth post omitted since we are limiting per-user to 3
    ]
  },
  // B is skipped since they have no posts
  {
    user: "C",
    posts: [
      { id: 45 }
    ]
  }
  // D is skipped because we are limiting total users to 2
]

我能够让它按预期工作,除了能够通过此查询限制每个用户返回的帖子:

SELECT *
FROM users
LEFT OUTER JOIN posts
ON posts.user_id = users.id
WHERE users.id IN (
    SELECT users.id
    FROM users
    LEFT OUTER JOIN posts
    ON posts.user_id = users.id AND posts.visibility = "public"
    GROUP BY users.id
    HAVING COUNT(posts.id) > 0
    LIMIT 1 -- Limits users fetched regardless of how many posts, but doesn't limit posts fetched themselves
)

但这感觉不必要的复杂,甚至不能正确解决问题。由于我们使用的是 Postgres,因此我尝试了一些涉及 LEFT OUTER JOIN LATERAL 的尝试,这似乎很有希望限制每个用户的帖子,但在设置返回用户的限制时让我感到困惑。

【问题讨论】:

  • LIMITing 没有ORDERing 很少有意义。
  • 会有订单,但我试图将其保留为最小示例

标签: sql postgresql


【解决方案1】:

您可以这样做(假设posts 有一个名为id 的列):

select *
from (
  select *, row_number(partition by p.user_id order by p.id) as rn
  from users u
  join posts p on p.user_id = u.id
  where u.user_id in (
    select user_id
    from (select distinct user_id from posts where visibility = 'public') x
    order by user_id
    limit 2 -- limits users to 2 (with public posts)
  )
) y
where rn <= 3 -- limits posts per user to 3

当帖子数量庞大且其中大部分是公共帖子时,可以通过使用横向表格表达式来提高性能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-31
    • 2014-07-20
    相关资源
    最近更新 更多