Cas généralExécution d'une jointure gauche sur un grand nombre à plusieurs table avec des conditions
Comment effectuer une jointure gauche dans plusieurs-à-plusieurs lorsque vous souhaitez ajouter une condition à l'étranger côté de la relation?
Cas particulier
Nous avons affaire à deux tables: team
et pool
. Il y a aussi une table team_pool
servant de table de jonction plusieurs-à-plusieurs entre eux. De plus, un pool
a une colonne stage_id
.
Je veux récupérer toutes les équipes avec le groupe de cette équipe pour une étape spécifique. Si le pool n'existe pas, je veux que le pool soit NULL. Exemple, résultats idéalisés:
+--------+----------+------+
| team | stage_id | pool |
+--------+----------+------+
| Team 1 | 2 | C |
| Team 2 | NULL | NULL | //this team doesn't belong to a pool for this stage (but it could belong to a pool for a different stage)
| Team 3 | 2 | G |
| Team 3 | 2 | H | //if a team belongs to a 2 pools for the same stage
| Team 4 | 2 | D |
Si c'est pertinent, j'utilise MySQL.
SQL
est ici le (simplifié) SQL utilisée pour créer les tables:
CREATE TABLE team (id BIGINT AUTO_INCREMENT, name VARCHAR(50), PRIMARY KEY(id));
CREATE TABLE team_pool (team_id BIGINT, pool_id BIGINT, PRIMARY KEY(team_id, pool_id));
CREATE TABLE pool (id BIGINT AUTO_INCREMENT, stage_id BIGINT, name VARCHAR(40) NOT NULL, PRIMARY KEY(id));
solution idéale
La solution idéale:
- Non exiger un ch ange to my schema (ORM le veut vraiment de cette façon)
- Requiert une seule requête non UNION.
tentatives de solutions
- Utiliser une jointure interne plutôt qu'une LEFT JOIN
team
-team_pool
etteam_pool
-pool
. Problème: nous perdons des équipes qui ne font pas partie d'une piscine - LEFT JOIN
team
-team_pool
etteam_pool
-pool
en utilisant une à la condition que lesstage_id
surpool
correspond à ce que nous recherchons. Problème: lorsqu'une équipe appartient à plusieurs pools, nous obtenons plusieurs résultats. L'ajout d'un GROUP BY n'aide pas.
EDIT: Solution Elu
Il y a beaucoup de bonnes solutions ici.
Étant donné que ma solution idéale n'est pas possible, je préfère ajouter stage_id
à team_pool plutôt que d'utiliser UNION ou des sous-requêtes. Cela a l'avantage supplémentaire de me permettre de faire valoir qu'une équipe ne peut appartenir qu'à un pool par étape. Il rend également les requêtes simples:
SELECT t.name, p.name, tp.stage_id FROM team t LEFT JOIN team_pool tp ON t.id = tp.team_id AND tp.stage_id = 2 LEFT JOIN pool p ON p.id = tp.pool_id
Comment l'équipe 2 a-t-elle un stage_id si pool est nul? – Snekse
Il ne devrait pas, je l'ai réparé. –
Pouvez-vous ajouter à vos résultats idéalisés pour montrer ce que vous attendez si une équipe appartient à plusieurs piscines? – Snekse