有两个模型Player和Team彼此关联为多对多,因此架构包含三个表players
,player_teams
和teams
。
鉴于每支球队可能由1或2名球员组成,如何通过已知球员ID找到球队?
在这个SQLFiddle http://sqlfiddle.com/#!15/27ac5
中答案 0 :(得分:2)
我认为问题陈述的第三个要点是错误的。没有球队3.在第三种情况下,我认为你想要回归球队2.(球员3所在的唯一球队。)
此查询需要2位信息 - 您感兴趣的玩家以及玩家数量。
SELECT team_id, count(*)
FROM players_teams
WHERE player_id IN (1,2)
GROUP BY team_id
HAVING count(*) = 2
-- returns team 1
SELECT team_id, count(*)
FROM players_teams
WHERE player_id IN (2)
GROUP BY team_id
HAVING count(*) = 1
-- returns teams 1 & 2
SELECT team_id, count(*)
FROM players_teams
WHERE player_id IN (3)
GROUP BY team_id
HAVING count(*) = 1
-- returns team 2
编辑:这是一个通过ruby使用它的例子,它可能会更清楚它是如何工作的......
player_ids = [1,2]
sql = <<-EOF
SELECT team_id, count(*)
FROM players_teams
WHERE player_id IN (#{player_ids.join(',')})
GROUP BY team_id
HAVING count(*) = #{player_ids.size}
EOF
答案 1 :(得分:1)
这是你在找什么?
select t.name
from teams t
inner join players_teams pt on t.id = pt.team_id
where pt.player_id = 1
- “好的,SQL给了我一个团队ID,这两个玩家都在一起玩”
select pt1.team_id
from players_teams pt1
inner join players_teams pt2 on pt1.team_id = pt2.team_id
where pt1.player_id = 1
and pt2.player_id = 2
答案 2 :(得分:1)
这是relational-division的简单案例。我们在这里汇集了一系列可能的技术:
虽然当前接受的答案中的查询应该有效,但对于每个示例,这些查询应该更短更快:
SELECT team_id -- returns team 1
FROM player_teams pt1
JOIN player_teams pt2 USING (team_id)
WHERE pt1.player_id = 1
AND pt2.player_id = 2;
SELECT team_id -- returns team 1 and 2
FROM player_teams
WHERE player_id = 2;
SELECT team_id -- returns team 2 (and 3 in the improved fiddle)
FROM player_teams
WHERE player_id = 3;
在案例2和案例3中,根本不需要JOIN
/ GROUP BY
/ HAVING
。
如果,您想要找到仅由播放器3 (以及否其他成员)组成的团队,请使用:< / p>
SELECT pt1.team_id -- returns team 3
FROM player_teams pt1
LEFT JOIN player_teams pt2 ON pt2.team_id = pt1.team_id
AND pt2.player_id <> pt1.player_id
WHERE pt1.player_id = 3
AND pt2.player_id IS NULL;
根据你的定义,这似乎不太可能:
鉴于每支球队可能由1或2名球员组成
相关:
SQL Fiddle改进了架构和扩展测试用例。
值得注意的是,我添加了FK约束并将UNIQUE
索引替换为PRIMARY KEY
约束。更多信息:
要使同一查询适用于两个player_id
或一个player_id
和NULL
,请使用NULL安全比较运算符IS NOT DISTINCT FROM
:
SELECT pt1.team_id -- returns team 3
FROM player_teams pt1
LEFT JOIN player_teams pt2 ON pt2.team_id = pt1.team_id
AND pt2.player_id <> pt1.player_id
WHERE pt1.player_id = 3
AND pt2.player_id IS NOT DISTINCT FROM 2;
我把两个案子都添加到小提琴里。总体来说可能会慢一点,并且肯定比只有一个player_id
的简单查询慢。
答案 3 :(得分:0)
您可以尝试以下代码:
DECLARE @player_id_to_search INT
SET @player_id_to_search = 1
SELECT DISTINCT teams.name
FROM teams
JOIN players_teams ON players_teams.team_id = teams.id
JOIN players ON players.id = players_teams.player_id
AND players.id = @player_id_to_search