ActiveRecord/SQL: 复杂的数据库查询 (outer_join / union / ?)
ActiveRecord/SQL: Complex DB query (outer_join / union / ?)
数据库查询:我想对所有参加培训的参与者进行一次数据库查询,显示所有参与者的姓名以及他们是否已经拥有一项特定技能。为了构建结果 table(参见示例),我想遍历查询结果,而不必为每个员工进行子查询。
|participant name|has_this_one_specific_skill|
|John Doe | yes |
|Alex Hardacre | yes |
|Abi Underwood | no |
|Kevin Wallace | yes |
|Connor Murray | no |
这是我的数据库结构。这样的结构会是什么样子?这是 left_outer_join 还是我要加入联盟?
class Employee < ApplicationRecord
has_many :participants
has_many :trainings,through: :participants
has_many :trained_skills,through: :trainings,source: :skill
end
class Training < ApplicationRecord
belongs_to :skill
end
class Participant < ApplicationRecord
belongs_to :training
belongs_to :employee
end
解决方案 1 - 推荐
Employee.left_joins(:trained_skills).where({skills: {name: ["MYSQL",nil]}}).pluck "employees.name,CASE WHEN skills.id IS NOT NULL THEN 'yes' else 'no' end"
注意:如果您需要 Employees 对象,您可以使用 select
而不是 pluck
。即######.select "employees.name as participant_name,CASE WHEN skills.id THEN 'yes' else 'no' end as has_this_one_specific_skill"
解决方案 2
Employee.joins("LEFT OUTER JOIN participants
ON participants.employee_id = employees.id LEFT OUTER JOIN trainings
ON trainings.id = participants.training_id LEFT OUTER JOIN skills
ON skills.id = trainings.skill_id AND skills.name = 'MYSQL'").
pluck "employees.name,CASE WHEN skills.id IS NOT NULL THEN 'yes' else 'no' end"
数据库查询:我想对所有参加培训的参与者进行一次数据库查询,显示所有参与者的姓名以及他们是否已经拥有一项特定技能。为了构建结果 table(参见示例),我想遍历查询结果,而不必为每个员工进行子查询。
|participant name|has_this_one_specific_skill|
|John Doe | yes |
|Alex Hardacre | yes |
|Abi Underwood | no |
|Kevin Wallace | yes |
|Connor Murray | no |
这是我的数据库结构。这样的结构会是什么样子?这是 left_outer_join 还是我要加入联盟?
class Employee < ApplicationRecord
has_many :participants
has_many :trainings,through: :participants
has_many :trained_skills,through: :trainings,source: :skill
end
class Training < ApplicationRecord
belongs_to :skill
end
class Participant < ApplicationRecord
belongs_to :training
belongs_to :employee
end
解决方案 1 - 推荐
Employee.left_joins(:trained_skills).where({skills: {name: ["MYSQL",nil]}}).pluck "employees.name,CASE WHEN skills.id IS NOT NULL THEN 'yes' else 'no' end"
注意:如果您需要 Employees 对象,您可以使用 select
而不是 pluck
。即######.select "employees.name as participant_name,CASE WHEN skills.id THEN 'yes' else 'no' end as has_this_one_specific_skill"
解决方案 2
Employee.joins("LEFT OUTER JOIN participants
ON participants.employee_id = employees.id LEFT OUTER JOIN trainings
ON trainings.id = participants.training_id LEFT OUTER JOIN skills
ON skills.id = trainings.skill_id AND skills.name = 'MYSQL'").
pluck "employees.name,CASE WHEN skills.id IS NOT NULL THEN 'yes' else 'no' end"