具有OR条件的多个内部联接的错误结果

时间:2013-03-26 17:18:09

标签: sql ruby-on-rails activerecord left-join inner-join

我有三个模型:EventCommentPhoto。活动同时包含has_many :commentshas_many :photos

我的目标是查找过去24小时内收到新评论和/或照片的所有活动。

假设存在两个事件,一个带有最近的评论,另一个带有最近的照片。

如果我使用单个连接单独查询它们,一切都按预期工作:

Event.joins(:comments).where("comments.created_at >= :today", :today => Time.now.beginning_of_day)

返回:[#<Event id: 1>]

Event.joins(:photos).where("photos.created_at >= :today", :today => Time.now.beginning_of_day)

返回:[#<Event id: 2>]

为什么在我将两个联接组合时:

Event.joins(:comments, :photos)
    .where("comments.created_at >= :today OR photos.created_at >= :today", :today => Time.now.beginning_of_day)

我收到[#<Event id: 2>, #<Event id: 2>] - 两次#2,但不是#1?

ARel生成的SQL

SELECT "events".*
FROM   "events"
       INNER JOIN "comments"
               ON "comments"."event_id" = "events"."id"
       INNER JOIN "photos"
               ON "photos"."event_id" = "events"."id"
WHERE  ( comments.created_at >= '2013-03-25 23:00:00.000000'
          OR photos.created_at >= '2013-03-25 23:00:00.000000' )  

2 个答案:

答案 0 :(得分:2)

我认为这是因为INNER JOIN。此查询只会带有与eventsphotos关联的comments。 您可以尝试在RDBMS上使用LEFT JOIN而不是INNER,并查看是否已获取两个结果。

答案 1 :(得分:1)

这是一个SQL问题:您必须指定LEFT JOIN而不是INNER JOIN。 include将为您完成:

Event.include(:comments, :photos).where(...).uniq