【问题标题】:Model Filtering Joins模型过滤连接
【发布时间】:2013-09-18 03:13:31
【问题描述】:

这是我的发帖模型。帖子通过帖子有很多user_id。我想返回用户 ID 为 2 和 3 的帖子。所以 ID 为 7 和 8 的帖子。

理想情况下,我的代码看起来像这样......但它不起作用

Post.joins(:postings).where("postings.user_id = ?", [2,3])

id  | post_id | user_id | created_at                | updated_at                |
+---+---------+--------+---------------------------+---------------------------+
| 1 | 7       | 1      | 2013-09-07 16:03:50 -0400 | 2013-09-07 16:03:50 -0400 |
| 2 | 7       | 2      | 2013-09-07 16:03:50 -0400 | 2013-09-07 16:03:50 -0400 |
| 3 | 7       | 3      | 2013-09-07 16:03:50 -0400 | 2013-09-07 16:03:50 -0400 |
| 4 | 8       | 2      | 2013-09-07 22:17:49 -0400 | 2013-09-07 22:17:49 -0400 |
| 5 | 8       | 3      | 2013-09-07 22:17:49 -0400 | 2013-09-07 22:17:49 -0400 |
| 6 | 8       | 6      | 2013-09-07 22:17:49 -0400 | 2013-09-07 22:17:49 -0400 |
| 7 | 12      | 3      | 2013-09-14 12:49:56 -0400 | 2013-09-14 12:49:56 -0400 |

添加评论

  • 我正在使用 Rails
  • 我希望能够保持 [2,3] 动态,因此数组中可以有 10 个条目或 2 个

  • Post 表没有 user_id 列。 Posting 模型有一个 user_id 列,而 User 表有一个 id 列。两者之间的关系已使用 has_many 关系建立。

【问题讨论】:

    标签: sql ruby-on-rails postgresql activerecord model


    【解决方案1】:

    我喜欢在having 子句中使用带有逻辑的聚合来解决这些问题,因为这是解决这类问题的最灵活的方法:

    select post_id
    from postings
    group by post_id
    having sum(case when user_id = 2 then 1 else 0 end) > 0 and
           sum(case when user_id = 3 then 1 else 0 end) > 0;
    

    having 子句中的每个条件都在计算与每个用户 ID 匹配的记录数。

    编辑:

    根据您在表上的索引,对于这个特定问题,以下可能实际上表现更好:

    select p2.user_id
    from postings p2 join
         postings p3
         on p2.post_id = p3.post_id and
            p2.user_id = 2 and
            p3.user_id = 3;
    

    编辑二:

    对于动态列表,您可以这样做:

    select post_id
    from postings
    where user_id in (2, 3, 4, 5, 6)
    group by post_id
    having count(distinct user_id) = 5;
    

    【讨论】:

    • 我使用了你后来的函数,没有“有 count(distinct user_id = 5)” 它与返回 7,8 的 Posting.where(:user_id => [2,3]) 相同, 12..这是不正确的。我只想看到那些 user_id 为 2 和 3 的,而不是那些有 2 或 3 的。
    • @ebbflowgo 。 . .这就是为什么你需要having count(distinct) = # of elements
    • 漂亮,谢谢!我现在明白你为什么要数 5。
    猜你喜欢
    • 2023-03-10
    • 2011-12-03
    • 1970-01-01
    • 2013-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-13
    相关资源
    最近更新 更多