gpt4 book ai didi

mysql - 具有 2 个不同可连接条件的 Ruby 查询

转载 作者:IT王子 更新时间:2023-10-28 23:50:02 24 4
gpt4 key购买 nike

我想找到所有拥有特定 LanguagesUsers 记录的用户。目前,我正在尝试查询连接表 LanguagesUsers,以获取用户拥有 2 种适当的 languages_id 和级别的所有实例

要找到只有一个关联的地方,可以这样做:

User.joins(:languages_users).where(languages_users: {language_id: 2, level: 5})

如何在查询中包含 2 个 languages_users,它们都为真?(例如,我想要 language_id: 2 level: 1 AND language_id: 3 level: 5)

我已经试过了,但是它返回了一个错误:

User.joins(:languages_users).where(languages_users: {language_id: 2, level: 5} AND languages_users: {language_id: 1, level: 3})

这一个返回一个空数组,即使肯定有用户拥有 2 个符合此条件的 languages_users:

User.joins(:languages_users).where(languages_users: {language_id: 2, level: 5}).where(languages_users: {language_id: 1, level: 3})

正确的格式是什么?谢谢!!

更新:LanugagesUser 是Languages 和Users 之间的连接表,有language_id, level, user_id

gem 'sqlite3', group: :development
group :production do
gem 'pg'
gem 'rails_12factor'
end

更新 2:由于两个答案都建议使用 or 语句,我认为我没有正确传达这个事实:

两个记录都存在。例如。我想知道哪些用户有 LanguagesUser(language_id: 1, level: 5) AND LanguagesUser(language_id:2, level:1)

最佳答案

你试过吗:

User.joins(:languages_users).where(languages_users: [{language_id: 2, level: 5}, {language_id: 1, level: 3}])

编辑:由于您使用的是 ActiveRecord >= 5,因此可以使用 .or 语法。结果有点冗长,但它应该可以工作,我相信你可以美化它:

User.joins(:languages_users).where(
languages_users: {language_id: 2, level: 5}).
or(
User.joins(:languages_users).where(
languages_users: {language_id: 1, level: 3}
)

编辑 2:我认为我明白你现在想要做什么,比我最初想象的要复杂,但我认为你将需要一个嵌套查询。如果您首先查询 languages_users 表并按 user_id 对它们进行分组,则可以对其应用 HAVING 子句以查找使用两种语言的用户.然后从该查询中选择 user_ids 并在用户表的简单查询中使用它们。由于您使用的是 postgres,因此以下内容可能有效。

languages = [{ language_id: 2, level: 5 }, { language_id: 1, level: 3 }]
User.where(users_with_all_languages(languages)

def users_with_all_languages(languages)
LanguagesUser.
select(:user_id).
group(:user_id).
having('array_agg(language_id) @> ARRAY[?] AND array_agg(level) @> ARRAY[?]',
languages.map { |x| x[:language_id] },
languages.map { |x| x[:level] }
)
end

或者,如果您对语言数据的格式具有灵 active ,则更简单:

language_ids = [2, 1]
language_levels = [5, 3]
User.where(users_with_all_languages(language_ids, language_levels)

def users_with_all_languages(ids, levels)
LanguagesUser.
select(:user_id).
group(:user_id).
having('array_agg(language_id) @> ARRAY[?] AND array_agg(level) @> ARRAY[?]', ids, levels)
end

我做过类似的事情,但不是在连接表上有两个条件,所以 ANDing 两个 array_agg 条件是我认为唯一的通配符...

关于mysql - 具有 2 个不同可连接条件的 Ruby 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41515944/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com