Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 反向查询有多个:通过_Sql_Ruby On Rails_Rails Activerecord - Fatal编程技术网

Sql 反向查询有多个:通过

Sql 反向查询有多个:通过,sql,ruby-on-rails,rails-activerecord,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 现在,假设

情景:

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
语义来实现这一点?从一个团队中获得所有球员很容易,但我找不到相反的方法

Team.join(:users).where('users.id in (?)', [1,5]).
select { |team| team.users.map(&:id).sort == [1,5] }
先前的答案(针对预编辑的问题) 这对你有用吗

Team.join(:users).where('users.id in (?)', [1,5])
您可以通过以下方式在用户模型上执行相同的操作:

# user.rb
has_many :teams, through: :works
has_many :works, foreign_key: :user_id
回应您的编辑和评论 哈奇:

Team.join(:users).where('users.id in (?)', [1,5]).
select { |team| team.users.map(&:id).sort == [1,5] }
更好


可以使用两个where子句:

一个用于获取所有的
团队
,其中正好有两个用户

Team.joins(:users).group("teams.id").having("count('distinct users.id') = 2").select("teams.id")
其次是让所有
团队
1
5
用户在一起

Team.joins(:users).where('users.id in (?)', [1,5]).group("teams.id").having("count('distinct users.id') = 2").select("teams.id")
这两者的交集应该能满足你的需要。 因此,要将这一切结合起来:

Team.where(id: Team.joins(:users).group("teams.id").having("count('distinct users.id') = 2").select("teams.id")).where(id: Team.joins(:users).where('users.id in (?)', [1,5]).group("teams.id").having("count('distinct users.id') = 2").select("teams.id"))

更新:啊!我是用纯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)
试试看,让我知道它是否适合你(在这里工作:和相同的例子,但有3名玩家:)


这不是在DB级别优化的,因为它使用了大量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)

他们是否必须在同一个团队中,可能与其他用户在一起,或者他们必须是该团队中唯一的玩家?@Yoshiji先生是该团队中唯一的玩家。这不起作用,因为我需要一个只有这两个玩家的团队。假设我有一个包含用户1、2和5的团队。这个查询也会带来这个团队。@MurifoX更新了答案上下文:我们正在寻找由用户1和2组成的团队。团队3有用户1和用户3。此团队#3将根据您的第一条指令找到(有2名玩家),然后再次找到,因为其中一名玩家在[1,2]中有id。我将尝试向您提供反馈