如何在Ruby on Rails中实现带子查询内连接的多表查询?
将SQL查询转换为Ruby on Rails风格查询
原始SQL查询
SELECT * FROM `books` INNER JOIN (SELECT * FROM `authors` GROUP by `author_id`) as variable ON variable.`id` = `books`.`id` INNER JOIN `student` ON `student`.`id` = variable.`id` WHERE (`books`.`id` = '1');
我的尝试(不符合需求)
我原本尝试了以下代码,但无法实现INNER JOIN (SELECT ... )的子查询形式:
Book.select('*').joins(author: :student).where("`books`.`id` = '1'").group("author.author_id")
正确的Rails风格查询
要实现带子查询的内连接,有两种可行的Rails风格方案:
方案1:直接拼接子查询字符串(简洁直观)
subquery = Author.select('*').group(:author_id).to_sql Book.select('*') .joins("INNER JOIN (#{subquery}) AS variable ON variable.id = books.id") .joins("INNER JOIN students ON students.id = variable.id") .where(books: { id: 1 })
方案2:使用Arel构建子查询(安全防注入)
author_subquery = Author.select(Arel.star).group(Author.arel_table[:author_id]).as('variable') books = Book.arel_table students = Student.arel_table Book.select('*') .joins(books.join(author_subquery, Arel::Nodes::InnerJoin).on(author_subquery[:id].eq(books[:id])).join_sources) .joins(books.join(students, Arel::Nodes::InnerJoin).on(students[:id].eq(author_subquery[:id])).join_sources) .where(books: { id: 1 })
说明:方案1适合简单场景,写法直接;方案2借助Rails底层的Arel构建查询,能有效避免SQL注入风险,更贴合ORM的规范写法。
内容的提问来源于stack exchange,提问作者kaserr
相关产品推荐
相关产品推荐

