Sql 同一列上具有多对多关系的多个where子句
设置。 我试图通过RoR的Sql 同一列上具有多对多关系的多个where子句,sql,ruby-on-rails,activerecord,arel,Sql,Ruby On Rails,Activerecord,Arel,设置。 我试图通过RoR的ActiveRecord::Relation实现一个复杂的搜索查询 到目前为止,索引操作代码中的代码如下所示: query = Member.all query = query.search(params[:q]) query = query.includes(:structures) query = query.with_structure(params[:party_id]) query = query.with_structure(params[:assembly
ActiveRecord::Relation
实现一个复杂的搜索查询
到目前为止,索引
操作代码中的代码如下所示:
query = Member.all
query = query.search(params[:q])
query = query.includes(:structures)
query = query.with_structure(params[:party_id])
query = query.with_structure(params[:assembly_id])
@members = query.paginate(:page => params[:page])
代码背后的想法是,我获取所有成员,然后在过滤器处于活动状态时删除成员search
和with_structures
是自定义类方法,其中执行where
子句
旁注:因此,如果您的解决方案涉及使用arel,请确保向我演示如何将arel::NODES转换回ActiveRecord::Relation
我的数据库如下所示:
query = Member.all
query = query.search(params[:q])
query = query.includes(:structures)
query = query.with_structure(params[:party_id])
query = query.with_structure(params[:assembly_id])
@members = query.paginate(:page => params[:page])
成员可以改变其在一个结构中的位置,因此他/她可以在同一个结构中有多个参与者。
问题
当party
和assembly
筛选器都处于活动状态时,查询将不返回任何内容,因为它在同一列上执行多个where子句
我尝试的
Member.joins(:structures)
.where(structures: { id: [1303, 1181] })
.group("members.id").count
或者,如果您更喜欢SQL:
SELECT COUNT(*) AS count_all, members.id AS members_id
FROM "members"
INNER JOIN "participations" ON "participations"."member_id" = "members"."id"
INNER JOIN "structures" ON "structures"."id" = "participations"."structure_id"
WHERE "structures"."id" IN (1303, 1181)
GROUP BY members.id
HAVING count(*)>1
这不起作用,因为许多记录的计数大于1,但它们只是两个结构中的一个结构的一部分,使用外部左连接也没有帮助
我也尝试过使用arel,但无法转换回ActiveRecord。我尝试使用q1.q2
我想要什么
我希望能够应用这两个where语句,而不会相互抵消。我希望能够写下这样的东西:
query = Member.all
q1 = query.with_structure(params[:party_id])
q2 = query.with_structure(params[:assembly_id])
query = q1.intersect q2
提前谢谢您,如果有什么不清楚的地方,请不要急于提问 您必须加入两次参与,每个id一次
from members m join participation p1
on m.id = p1.member_id and p1.structure_id = 1303
join participation p2 on m.id = p2.member_id and p2.structure_id = 1181
我不确定您是否需要加入结构,因为您似乎没有从中进行选择。您必须加入两次参与,每个id一次
from members m join participation p1
on m.id = p1.member_id and p1.structure_id = 1303
join participation p2 on m.id = p2.member_id and p2.structure_id = 1181
我不确定您是否需要加入结构,因为您似乎没有从中进行选择。我想与SO分享我作为问题解决方案所做的工作。我不会接受我自己的答案,因为@Dan Bracuk帮了我一点忙,这不公平 在控制器中:
query = Member.all
query = query.search(params[:q])
ids = params.slice(:party_id, :assembly_id).values.delete_if { |v| v.blank? }.map { |v| v.to_i }
query = query.create_joins ids
@members = query.paginate(:page => params[:page])
这在成员模型中:
def self.create_joins structure_ids
if structure_ids.empty?
all
else
structure_ids.each_with_index.map do |id, idx|
joins("INNER JOIN 'participations' 'p#{idx}' ON 'p#{idx}'.'member_id' = 'members'.'id'")
.where("p#{idx}.structure_id" => id).uniq
end.reduce(:merge)
end
end
我们的想法是,我们为
srstructure\u id
中的每个id创建一个单独的连接和查询,然后使用reduce
方法将它们合并在一起。我想与SO分享我作为问题解决方案所做的工作。我不会接受我自己的答案,因为@Dan Bracuk帮了我一点忙,这不公平
在控制器中:
query = Member.all
query = query.search(params[:q])
ids = params.slice(:party_id, :assembly_id).values.delete_if { |v| v.blank? }.map { |v| v.to_i }
query = query.create_joins ids
@members = query.paginate(:page => params[:page])
这在成员模型中:
def self.create_joins structure_ids
if structure_ids.empty?
all
else
structure_ids.each_with_index.map do |id, idx|
joins("INNER JOIN 'participations' 'p#{idx}' ON 'p#{idx}'.'member_id' = 'members'.'id'")
.where("p#{idx}.structure_id" => id).uniq
end.reduce(:merge)
end
end
我们的想法是为
sructure\u id
中的每个id创建一个单独的连接和查询,然后使用reduce
方法将它们合并在一起。我会测试你的提议,然后回复你。谢谢。再次你好。:)你说得对。进行多个连接是一种方法。然而,我仍在试图找出如何以最优雅的方式实现代码,这就是-保持activerecord关系,而不使用类似于Member.find\u by\u sql(sql代码)
的东西。这将是最后的手段。过去我曾多次尝试使用rails提供的方法拆分联接,但都没有成功。Member.joins(:participations)。其中(“participations.structures\u id”=>1303)。joins(:participations)。其中(“participations.structures\u id”=>1181)对于rails只有一个连接:/Hi Dan。我会测试你的提议,然后回复你。谢谢。再次你好。:)你说得对。进行多个连接是一种方法。然而,我仍在试图找出如何以最优雅的方式实现代码,这就是-保持activerecord关系,而不使用类似于Member.find\u by\u sql(sql代码)
的东西。这将是最后的手段。过去我曾多次尝试使用rails提供的方法拆分联接,但都没有成功。成员连接(:participations)。其中(“participations.structures\u id”=>1303)。连接(:participations)。其中(“participations.structures\u id”=>1181)对于rails只有一个连接:/