You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 15:05:43