鉴于两个模型Player
和Team
如何选择两个玩家特定玩家所属的所有球队?
示例Rails模型和db表设置:
Rails模型:
class Player < ActiveRecord::Base
has_and_belongs_to_many :teams, uniq: true
end
class Team < ActiveRecord::Base
has_and_belongs_to_many :players, uniq: true
end
SQL表
teams players players_teams
+----------------------------------------------------+
| id | name | | id | name | | player_id | team_id |
+----+------+ +----+------+ +-----------+---------+
| 1 | Foo | | 1 | Jack | | 1 | 1 |
| 2 | Bar | | 2 | Jill | | 1 | 2 |
| | | | | | | 2 | 1 |
如何选择所有同时拥有Jack和Jill的球队? (在这种情况下,只是Foo团队。)
答案 0 :(得分:2)
这是一个非常棘手的问题!它不仅仅是where子句中的OR / AND。 在这里,您可以使用GROUP BY和MAX
在单个SQL查询中找到解决方案SELECT t.*
FROM teams t
JOIN players_teams pt ON t.id = pt.team_id
JOIN players p ON p.id = pt.player_id
WHERE p.name IN ('Jack', 'Jill')
GROUP BY t.id
HAVING MAX(p.name = 'Jack') = 1 AND MAX(p.name = 'Jill') = 1
在ActiveRecord中应该是这样的(未经测试的)
Team.joins(:players).where("players.name IN (?)", ["Jack", "Jill"])
.group("teams.id")
.having("MAX(players.name = ?) = 1 AND MAX(players.name = ?) = 1", "Jack", "Jill")
答案 1 :(得分:1)
您可以获得两个单独查询的交集,例如
Team.includes(:players).where(players: { name: 'Jack' }) & Team.includes(:players).where(players: { name: 'Jill' })
对于单个查询,请尝试以下
Team.includes(:players).where(players: { name: ['Jack', 'Jill'] }).group('teams.id').having('COUNT(players.id) = 2')
答案 2 :(得分:0)
Teams.all(:include => :player, conditions => ["player.name in (?)", ["Jack","Jill"]])
答案 3 :(得分:0)
这是我提出的使用子查询的解决方案。有没有人有更清洁的AREL方式来实现这个目标?
SELECT te1.* FROM (
SELECT DISTINCT "teams".* FROM "teams"
INNER JOIN "players_teams" ON "teams"."id" = "players_teams"."team_id"
WHERE "players_teams"."player_id" = 2
) te1 INNER JOIN "players_teams" ON "te1"."id" = "players_teams"."team_id"
WHERE "players_teams"."player_id" = 1;