3 votes

SQL: GROUP BY après JOIND sans écraser les lignes?

J'ai une table des ligues de basketball, une table des équipes et une table des joueurs comme ceci :

LIGUES
ID   |   NOM    |
------------------
1    |   NBA     |
2    |   ABA     |

ÉQUIPES :
ID   |   NOM    |  ID_LIGUE
------------------------------
20   |   BULLS   |    1
21   |   KNICKS  |    2

JOUEURS :
ID   |   ID_ÉQUIPE  |  PRÉNOM | NOM | 
---------------------------------------------
1    |      21    |   John      |  Starks   |    
2    |      21    |   Patrick   |  Ewing    |    

Étant donné un ID de Ligue, je voudrais récupérer tous les noms des joueurs et leur ID d'équipe de toutes les équipes de cette ligue, alors je fais ceci :

SELECT t.id AS team_id, p.id AS player_id, p.first_name, p.last_name
FROM teams AS t
JOIN players AS p ON p.team_id = t.id
WHERE t.league_id =  1

ce qui renvoie :

[0] => stdClass Object
    (
        [team_id] => 21
        [player_id] => 1
        [first_name] => John
        [last_name] => Starks
    )

[1] => stdClass Object
    (
        [team_id] => 21
        [player_id] => 2
        [first_name] => Patrick
        [last_name] => Ewing
    )

+ environ 500 autres objets...

Comme je vais utiliser ce résultat pour peupler un menu déroulant pour chaque équipe contenant la liste des joueurs de chaque équipe, je voudrais regrouper mon résultat par ID d'équipe, afin que la boucle pour créer ces menus déroulants ait seulement à parcourir chaque ID d'équipe au lieu de tous les 500+ joueurs à chaque fois.

Mais lorsque j'utilise le GROUP BY comme ceci :

SELECT t.id AS team_id, p.id AS player_id, p.first_name, p.last_name
FROM teams AS t
JOIN players AS p ON p.team_id = t.id
WHERE t.league_id =  1
GROUP BY t.id

cela ne renvoie qu'un joueur de chaque équipe comme ceci, écrasant tous les autres joueurs de la même équipe en raison de l'utilisation des mêmes noms de colonnes.

[0] => stdClass Object
    (
        [team_id] => 21
        [player_id] => 2
        [first_name] => Patrick
        [last_name] => Ewing
    )
[1] => stdClass Object
    (
        [team_id] => 22
        [player_id] => 31
        [first_name] => Shawn
        [last_name] => Kemp
    )
etc...

Je voudrais obtenir quelque chose comme ceci :

[0] => stdClass Object
    (
        [team_id] => 2

        [player_id1] => 1
        [first_name1] => John
        [last_name1] => Starks
        [player_id2] => 2
        [first_name2] => Patrick
        [last_name2] => Ewing

        +10 autres joueurs de cette équipe...
    )

    +25 autres équipes...

Est-ce possible d'une manière ou d'une autre ?

4voto

Aleksandar Vučetić Points 6983

Vous ne pouvez pas faire cela en SQL, car vous ne pouvez pas représenter ce résultat sous forme de jeu de données. Vous voulez renvoyer un objet complexe. Ce que vous pouvez faire, c'est gérer cela dans le code, et vous aider en renvoyant un jeu de données trié par team_id. Chaque fois que votre team_id change, il est alors temps de créer un nouvel objet dans votre code et de le remplir avec une nouvelle liste de joueurs.

Cela ressemblerait à ceci (la syntaxe pourrait ne pas être correcte):

Jeu de données retourné:

team_id|player_id|first|last
1|1|f1|l1
1|2|f2|l2
1|3|f3|l3
2|5|f5|l5
2|6|f6|l6

Et lorsque cela est retourné dans votre code

$lastTeamId=0;
$output=array();
foreach($results as $row){
  if($lastTeamId != $row["team_id"]){
    $lastTeamId = $row["team_id"];
    $output[$lastTeamId] = array();
  }

  $newPlayer = null;
  $newPlayer->id = $row["player_id"];
  $newPlayer->first = $row["first"];
  $newPlayer->last = $row["last"];
  $output[$lastTeamId][] = $newPlayer;
}

0voto

Dans MySQL, vous pourriez regrouper par team_id puis SÉLECTIONNER GROUP_CONCAT(détail du joueur ...). Mais cela rencontre des restrictions et n'est pas l'approche relationnelle typique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X