sql - 对 has_many 进行反向查询 :through

标签 sql ruby-on-rails rails-activerecord

场景:

Team
has_many :players, dependent: :destroy
has_many :users, through: :players

Player
belongs_to :team
belongs_to :user

User

所以,假设我有 4 个拥有不同用户的团队:

Team 1
User 1, User 2

Team 2
User 2, User 3

Team 3
User 1

Team 4
User 2, User 4, User 5

现在,假设我有两个用户的 ID(用户 1用户 5),并且我想知道是否有任何团队由 <仅限这两名球员。假设我有一个由用户 1、2 和 5 组成的团队。查询不应包含该团队。

我如何使用有利于我的ActiveRecord语义来做到这一点?从一个团队中获取所有玩家很容易,但我找不到相反的方法。

最佳答案

更新:啊!我用纯 SQL 得到了它:

users = User.first(2)
Team.joins(:users).group('teams.id').having('SUM( CASE WHEN users.id in (?) THEN 1 ELSE -1 END ) = ?', users, users.count)

尝试一下并告诉我它是否适合您(在这里工作: http://sqlfiddle.com/#!17/bb2a9/8 和相同的示例,但有 3 个玩家: http://sqlfiddle.com/#!17/bb2a9/10 )


这没有在数据库级别进行优化,因为它使用了大量的 ruby​​/rails 代码,但是你可以尝试一下吗?

users = User.first(2)
# find teams with that exact number of players associated
teams = Team.joins(:users).group('teams.id').having('COUNT(users.id) = ?', users.count)
# find players referencing to those teams with other users than the ones specified
players_to_ignore = Player.where(team_id: teams).where('user_id NOT IN (?)', users)
# get Teams where associated players id is not in the previous list
Team.where(id: teams).joins(:players).where('players.id NOT IN (?)', players_to_ignore)

关于sql - 对 has_many 进行反向查询 :through,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45703606/

相关文章:

mysql - 单个查询中的多个删除

sql - 从 id 中间拉出 3 位数字并按奇偶数排序

Mysql Coalesce 对待字段的方式与 where 不同

ruby-on-rails - 如何进行数据库迁移以创建具有特定属性的表?

mysql - Rails/Devise/ActiveRecord 不接受 unicode 字符

php - 如何有效地将 1 行与数据库中的所有其他行进行比较

ruby-on-rails - Ruby Net::HTTP - 停止自动转义引号?

ruby-on-rails - Heroku、CarrierWave、MiniMagick : random tmp file missing

ruby-on-rails - Rails where 条件使用 NOT NIL

ruby-on-rails - 如何获取 Rails 表中每个不同名称的第 n 条记录?