2014-04-23 1 views
0

J'ai une relation M2M sur deux tables dans une base de données SQL, comme suit:relation Sélection avec les touches exactes dans un grand nombre à plusieurs

Players 
------- 
Name 
ID 

Teams 
------ 
Name 
ID 

PlayersTeams 
------ 
PlayerID 
TeamID 

Une équipe est composée de 1 ou plusieurs joueurs.

Je voudrais demander à une équipe compte tenu de ses ID de joueur, et renvoie uniquement l'équipe qui contient exactement les joueurs, ni plus, ni moins. Donc, interroger une équipe avec des joueurs (1,2,3) ne retournerait l'équipe avec les joueurs 1,2,3, et pas une équipe avec les joueurs 1,2,3,4.

Est-ce possible dans une seule requête?

J'ai un sqlfiddle je suis en train de travailler dehors ici: http://sqlfiddle.com/#!2/27799/8

dans cet exemple que je voudrais être en mesure de choisir l'équipe « john et mick » en questionnant avec les ID de joueur 1 et 2 ...

mise à jour dans cette sqlfiddle http://sqlfiddle.com/#!2/27799/69 je peux sélectionner l'équipe ID 2 ("john et mick") mais il obtient également ID de l'équipe 4 ("john, mick et Trev"). Besoin de le filtrer jusqu'à JUSTE 2.

+0

Quel SGBD utilisez-vous? Postgres? Oracle? –

+0

@a_horse_with_no_name postgres – market

Répondre

3
select TeamId 
from PlayersTeams 
group by TeamId 
having count(*) = sum(case when playerid in (1,2) then 1 else 0 end) 
and count(*) = 2 

Vous n'êtes pas familier avec MySQL, donc je ne t sais comment obtenir la longueur de la liste des joueurs (le count(*) =2) de faire est entièrement dynamique, mais tu obtiens le point.

+0

Brillant! Même logique mais beaucoup plus belle comparée à la mienne. – MinhD

+0

Solution très élégante, merci. – market

0

J'ai ajouté le joueur 3 dans l'équipe 3 pour créer tous les cas possibles. Voici ma réponse:

SELECT t.* 

FROM playersteams a, 

    teams t 

WHERE a.teamid = t.id 

AND (SELECT COUNT(*) FROM playersteams c 
    WHERE c.teamid = a.teamid 
    AND c.playerid = 2) = 1 

AND (SELECT COUNT(*) FROM playersteams c 
    WHERE c.teamid = a.teamid 
    AND c.playerid = 3) = 1 

GROUP BY t.id, t.name 

HAVING COUNT(a.playerid) = (SELECT COUNT(*) FROM players WHERE id IN (2,3)); 

SQL Fiddle: demo

Questions connexes