【问题标题】:Eager loaing with LEFT OUTER JOIN and multiple conditions in the ON clause使用 LEFT OUTER JOIN 和 ON 子句中的多个条件进行急切加载
【发布时间】:2025-12-15 09:10:01
【问题描述】:

我有不同语言的词义和翻译,这里是架构http://sqlfiddle.com/#!15/cba5e/2 我需要得到所有的感官,只有西班牙翻译(代码“es”),所以查询应该看起来像

SELECT *
FROM senses s 
LEFT OUTER JOIN translations t ON
    s.id = t.sense_id AND t.language_code = 'es';

我可以使用 eager_load/includes/.. 吗?

类似代码

Sense.includes(:translations).where(translations: { language_code: 'es' })

不起作用,因为它在 WHERE 子句中指定条件并生成类似

的查询
SELECT *
FROM senses s 
LEFT OUTER JOIN translations t ON s.id = t.sense_id
WHERE t.language_code = 'es';

而且我只对“es”翻译有感觉。但我需要所有感官 + 西班牙翻译,看看区别:http://sqlfiddle.com/#!15/cba5e/2http://sqlfiddle.com/#!15/cba5e/3

来自https://www.postgresql.org/docs/current/static/queries-table-expressions.html: ON 子句中的限制在连接之前处理,而 WHERE 子句中的限制在连接之后

处理

【问题讨论】:

  • 我已经回答了下面的答案,请抽时间评估一下

标签: ruby-on-rails ruby-on-rails-4 rails-activerecord


【解决方案1】:

找到了一种使用左外连接来完成急切加载的方法。它是通过使用与条件的关联来完成的。

Sense (model)
has_many es_translations -> { where(language_code: 'es') },
           :class_name => "Translations",
           :foreign_key => "foreign_key_column"

# references is used to ensure eager load
Sense.includes(:es_translations).references(:es_translations) 

这样,它将在 ON 查询上创建一个带有条件的左外连接。

【讨论】:

    【解决方案2】:

    这样就可以了

    Sense.includes(:translations).where('translations.language_code = ?', 'es')
    

    includes LEFT OUTER JOIN

    【讨论】:

    • 好吧,我正在写答案,并且正在做一些其他工作,但这并不意味着你会否决它
    • 由于这是一个重复的后来的答案,除了发生在这个页面上之外没有其他用处。它应该被清楚地标记为这样,并且downvote是这样做的方式。每个人都可以发布重复的答案,但与其保留它,不如对之前的答案进行投票。
    • 正如我刚才所说,我正在回答并同时做我的工作。我怎么知道有人已经发布了相同的答案
    • 当然是在发布你的横幅之前点击1 new answer has been posted横幅。
    • @Deepak 这就是为什么我在后置短语的标题中加上“...... ON 子句中的条件”;-)
    最近更新 更多