2011-06-09 6 views
0

J'ai deux tables de base de données MySQL: l'une contenant une liste de championnats et l'autre un changement de titre d'enregistrement. Les schémas ressemblent à ceci:Commander une requête MySQL avec LEFT JOIN

championships

id INT AUTO_INCREMENT PRIMARY_KEY 
name VARCHAR(255) NOT NULL UNIQUE 
rank INT(2) NOT NULL DEFAULT '1' 

title_history

id INT AUTO_INCREMENT PRIMARY_KEY 
championship INT FOREIGN_KEY REFERENCES (championships.id) 
winner VARCHAR(255) NOT NULL 
date_won DATE NOT NULL 

Je veux être en mesure de tirer le dernier détenteur du titre. Je peux en tirer titulaire d'un titre avec la requête MySQL LEFT JOIN suivante:

SELECT c.id, h.winner 
FROM championships c 
LEFT JOIN title_history h 
ON c.id = h.championship 
ORDER BY c.rank ASC 

Cependant, cela tire juste le premier résultat pour chaque championnat sur un index par défaut (id je présume). Lorsque j'ai essayé d'ajouter ORDER BY h.date_won en tant que clause, la requête semble tomber et ne renvoie aucun résultat.

Est-ce que je fais quelque chose de mal?

+0

Qu'est-ce que 'championships.rank' représente? –

+0

C'est pour que je puisse commander les championnats en importance. –

+1

Je ne comprends pas vraiment si vous voulez d'abord pour chaque championnat, alors vous devriez avoir un certain regroupement non seulement gauche joindre, est-ce que cette requête vous collé ici incomplète? Changer 'order by' ne change pas le nombre de lignes que vous obtenez alors qu'est-ce que vous avez exactement changé dans cette requête? –

Répondre

0

Je pense que je l'ai craqué! La requête suivante semble me donner ce que je dois:

SELECT c.id, c.name, h.winner 
FROM championships c 
LEFT JOIN title_history h 
ON c.id = h.championship 
GROUP BY c.id 
ORDER BY c.rank ASC, h.date_from ASC 

EDIT: Je n'ai pas craqué. Comme je suis en train de regrouper par ID de championnat, je reçois maintenant seulement le premier gagnant du titre, même s'il y a eu des titres gagnants après.

EDIT 2: résolu avec la requête suivante:

SELECT friendly_name, 
(SELECT winner FROM title_history WHERE championship = c.id ORDER BY date_from DESC LIMIT 1) 
FROM championships AS c 
ORDER BY name 
+0

Je ne pense pas que vous ayez besoin de 'GROUP BY c.id' car' id' est la clé primaire de la table 'championships'. –

+0

si vous groupez par c.Id ... comment est-il possible d'utiliser d'autres colonnes, ressemble à la syntaxe d'incorect –

+0

@Piotr: C'est correct dans MySQL :) –

0

Cela montrera que le dernier (décidé) championnat:

SELECT winner 
FROM title_history 
ORDER BY date_won DESC 
LIMIT 1 

Pour afficher tous les championnats et leurs gagnants, votre LEFT JOIN tentative semble correcte. Peut-être que vous voulez commander les résultats par date_won:

SELECT c.id, h.winner 
FROM championships c 
    LEFT JOIN title_history h 
    ON c.id = h.championship 
ORDER BY date_won DESC 

ou l'ordre par ordre d'importance (et par date_won pour les championnats avec la même importance):

SELECT c.id, h.winner 
FROM championships c 
    LEFT JOIN title_history h 
    ON c.id = h.championship 
ORDER BY c.rank ASC 
     , h.date_won DESC 
+0

Non, car je veux le dernier gagnant pour chaque championnat; mais un championnat ne peut avoir aucun gagnant même si je veux toujours un résultat pour ce résultat, d'où le 'LEFT JOIN'. –

+0

Ceci n'attrapera pas les championnats sans les gagnants (en cours de lecture) – CristiC

+0

@Martin: Je pensais que vous aviez dit * "Je veux le dernier détenteur du titre" * –