模型过滤连接

时间:2013-09-18 03:13:31

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

这是我的发布模式。帖子通过帖子有很多user_id。我想返回包含user_id 2和3的帖子。所以ID为7和8的帖子。

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

Post.joins(:帖子).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关系设置了两者之间的关系。

1 个答案:

答案 0 :(得分: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;

编辑II:

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

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