我正在搜索系统中与仅特定报告列表相关联的用户。
每个用户都可以与许多不同的报告相关联。我有三份报告需要与其他报道不同。让我们说他们有1个,2个和3个ID。
我试过了:
User.joins(:user_reports).where(active: true, user_reports: {report_id: [1,2,3]})
这很接近,但它会找到与我要查找的报告相关联的用户,但它也会找到与这些报告相关联的人和其他报告。
如何找到与仅这些特定报告或其任意组合相关联的用户?
答案 0 :(得分:1)
以下内容将有所帮助:
disallowed_user_ids = UserReport.
where("report_id NOT IN (?)", report_ids).
pluck("DISTINCT user_id")
User.
joins(:reports).
where("users.id NOT IN (?)", disallowed_user_ids).
group("users.id")
也可能使用丑陋的子查询:
User.
joins(:reports).
where("users.id NOT IN (
SELECT user_id FROM user_reports WHERE report_id IN (?)
)", report_ids).
group("users.id")
如果您的数据库中的每个用户至少有一个报告,那么您可以放弃joins
和group
。
<强>更新强>
以下是一个选项:
report_ids_str = report_ids.join(',')
User.
select("COUNT(r2.id) AS r2c, #{User.column_names.join(',')}").
joins("INNER JOIN reports AS r1 ON (
r1.user_id = users.id AND r1.id IN (#{report_ids_str}))").
joins("LEFT OUTER JOIN reports AS r2 ON (
r2.user_id = users.id AND r2.id NOT IN (#{report_ids_str}))").
group("users.id").
where("r2c = 0")
您可以将select
和where
替换为having("COUNT(r2.id) = 0")
。