查找至少有一个成员是列表一部分的组列表(rails、SQL)
我有一个简单的has_许多:通过安排,如下所示查找至少有一个成员是列表一部分的组列表(rails、SQL),sql,ruby-on-rails,sqlite,postgresql,Sql,Ruby On Rails,Sqlite,Postgresql,我有一个简单的has_许多:通过安排,如下所示 # employee.rb class Employee < ActiveRecord::Base has_many :group_assignments has_many :groups, through: :group_assignments # ... end # group.rb class Group < ActiveRecord::Base has_many :group_assignments has
# employee.rb
class Employee < ActiveRecord::Base
has_many :group_assignments
has_many :groups, through: :group_assignments
# ...
end
# group.rb
class Group < ActiveRecord::Base
has_many :group_assignments
has_many :employees, through: :group_assignments
# ...
end
# group_assignment.rb
class GroupAssignment < ActiveRecord::Base
belongs_to :employee
belongs_to :group
end
#employee.rb
类Employee
我有一份员工名单。对于该列表,我想抓取至少包含该列表中一名员工的每个组。我该如何以一种不会极度低效的方式完成这项工作?我对Rails还很陌生,对SQL也很陌生,我很茫然。我在开发中使用SQLite,在生产中使用PostgreSQL。这是一般的想法,但根据您的数据,您可能需要选择distinct
Group.includes(:group_assignments => :employee).where(:employee => {:id => ?}, @employees.map(&:id))
试一试
对于名为
employees\u list
的员工列表,这将起作用:
Group.includes(:employees).where('employees.id' => employees_list.map(&:id))
这大致就是您将获得的SQL类型:
SELECT "groups"."id" AS t0_r0,
"groups"."created_at" AS t0_r1, "groups"."updated_at" AS t0_r2,
"employees"."id" AS t1_r0, "employees"."created_at" AS t1_r1, "employees"."updated_at" AS t1_r2
FROM "groups"
LEFT OUTER JOIN "group_assignments" ON "group_assignments"."group_id" = "groups"."id"
LEFT OUTER JOIN "employees" ON "employees"."id" = "group_assignments"."employee_id"
WHERE "employees"."id" IN (1, 3)
因此,发生的情况是,组
和组分配
表首先与左侧外部联接联接(将组分配
表中的组id
列与组
表中的id
列相匹配),然后再次使用左外联接将employees
与employees
表中的employeed\u id
匹配到group\u assignments
表中的id
列
然后,我们选择'employees.'id'
(员工的id)位于员工列表中员工数组中的所有行,我们使用映射员工列表
:员工列表.map(&:id)
将员工列表
映射到他们的id。map(&:id)
这里是map{e|e.id}
的简写
请注意,您可以在此处使用joins
而不是includes
,但如果一名员工是多个组的成员,则会得到重复的。这是一件微妙但有用的事情
希望这有意义 你的意思是在group.rb.中“有很多:员工,通过::组分配”。。!!是的,很抱歉。修好了。这看起来很棒,非常感谢。几个问题:1)我假设在
:group\u assignments=>:employee
,:employee
中,员工的id是否存储在group\u assignments表中?2) map返回一个迭代器,对吗?所以你可以把迭代器传给它?部分3) 什么是&in&:id
?很抱歉没有人,再次感谢您这么快的回复。这是简短的,谢谢。你能解释一下where部分发生了什么吗?太棒了。如果您可以将员工列表重命名为employees\u list
,而不是employees
,以使事情更清楚,我将接受答案。完成!希望我没有错过任何东西。酷。所以map(&:id)实际上是返回一个id数组,而不是所有id上的迭代器。知道了!回答得很好。我会再打给你的,现在没时间回答。
SELECT "groups"."id" AS t0_r0,
"groups"."created_at" AS t0_r1, "groups"."updated_at" AS t0_r2,
"employees"."id" AS t1_r0, "employees"."created_at" AS t1_r1, "employees"."updated_at" AS t1_r2
FROM "groups"
LEFT OUTER JOIN "group_assignments" ON "group_assignments"."group_id" = "groups"."id"
LEFT OUTER JOIN "employees" ON "employees"."id" = "group_assignments"."employee_id"
WHERE "employees"."id" IN (1, 3)