Rails“嵌套”加入查询

时间:2013-04-01 22:08:12

标签: ruby-on-rails activerecord syntax

在我的数据库中,我有以下表格和关系:

  

检查 --has_many--< 样本 --has_many--< 结果

如果样本中有一个或多个与之关联的结果,则会将其视为“已分析”。如果对所有样品进行分析,则视为“完整”。我需要找到所有“不完整”的检查;也就是说,所有检查至少有一个尚未分析的样本。

我在mysql数据库中执行此操作的查询是

SELECT DISTINCT inspections.*
    FROM inspections
    JOIN samples s ON inspections.id = s.inspection_id
    LEFT OUTER JOIN results r ON r.`sample_id` = s.`id`
    WHERE r.id IS NULL

我正在尝试将其转换为一个很好的ActiveRecord find调用(除了find_by_sql),但我不确定如何获得“嵌套”关联的左连接(术语?)进入语法。

任何人都可以帮助我吗?顺便说一句,这是一个Rails 2.3应用程序。


现在我有

Inspection.all(:select => "distinct inspections.*",
  :joins => "join samples on samples.inspection_id = inspections.id " +
    "left join results on results.sample_id = samples.id",
  :conditions => "results.id is null")

它可以工作,但仍然看起来未定义,并且太接近整个sql语句。有什么比这更干净的东西吗?

1 个答案:

答案 0 :(得分:1)

在find语句中使用:include

Inspection.find(:all, :include => {:samples => :results})

修改

之前我错过了INNER JOINLEFT JOIN的组合。道歉。

虽然它不会生成相同的查询,但您可以添加其他位置检查以过滤掉没有任何样本的检查。

Inspection.find(:all,
    :select => "DISTINCT inspections.*",
    :include => {:samples => :results},
    :conditions => "results.id IS NULL AND samples.id IS NOT NULL")

但请注意,这种方法的效果不如使用JOIN s那样。