2010-06-15 21 views
2

Mon scénario: Il existe 3 tables pour stocker des informations sur les émissions télévisées; saison, épisode et épisode_translation.Aide SQL LEFT JOIN

Mes données: Il y a 3 saisons, avec 3 épisodes chacun, mais il n'y a que la traduction pour un épisode.

Mon objectif: Je veux obtenir une liste de toutes les saisons et tous les épisodes d'un spectacle. S'il y a une traduction disponible dans une langue spécifiée, montrez-la, sinon affichez null.

Ma tentative pour obtenir la série 1 des informations dans la langue 1:

SELECT 
    season_number AS season,number AS episode,name 
    FROM 
    season NATURAL JOIN episode 
    NATURAL LEFT JOIN episode_trans 
    WHERE 
    id_serie=1 AND 
    id_lang=1 
    ORDER BY 
    season_number,number 

Résultat:

+--------+---------+--------------------------------+ 
| season | episode | name       | 
+--------+---------+--------------------------------+ 
|  3 |  3 | Episode translated into lang 1 | 
+--------+---------+--------------------------------+ 

résultat attendu

+-----------------+--------------------------------+ 
| season | episode| name       | 
+-----------------+--------------------------------+ 
|  1 |  1 | NULL       | 
|  1 |  2 | NULL       | 
|  1 |  3 | NULL       | 
|  2 |  1 | NULL       | 
|  2 |  2 | NULL       | 
|  2 |  3 | NULL       | 
|  3 |  1 | NULL       | 
|  3 |  2 | NULL       | 
|  3 |  3 | Episode translated into lang 1 | 
+--------+--------+--------------------------------+ 

DB pleine vidage http://pastebin.com/Y8yXNHrH

+0

Ceci devrait être balisé MySQL –

+0

Quelle version de SQL? – AllenG

+0

Vous spécifiez id_lang = 1 dans votre clause where. Si vous enlevez cela, cela renvoie-t-il le résultat attendu? – Shaded

Répondre

1

Vous avez probablement besoin de déplacer le id_lang = 1 dans la clause LEFT JOIN au lieu de la clause WHERE. Pensez-y de cette façon ... pour toutes ces lignes sans traduction, LEFT JOIN vous renvoie des valeurs NULL pour toutes ces colonnes de traduction. Ensuite, dans la clause WHERE, vous vérifiez si elle est égale à 1, ce qui revient bien sûr à FALSE.

Il serait probablement plus facile si vous avez inclus votre code dans la question la prochaine fois au lieu d'un lien.

1

Pouvez-vous essayer d'utiliser

LEFT OUTER JOIN 

au lieu de

NATURAL LEFT JOIN 
+0

J'ai changé "NATURAL LEFT JOIN episode_trans" en "LEFT OUTER JOIN épisode_trans USING (id_episode) "mais j'obtiens le même résultat –

+0

Cochez la réponse d'Anthony Faull, il a raison, les critères devraient être dans les critères de jointure, sinon il n'y a rien pour remplir la jointure. –

2
LEFT JOIN episode_trans 
    ON episode_trans.id_episode = episode.id_episode 
    AND episode_trans.id_lang = 1 
WHERE id_serie=1 
+0

Merci Anthony, il n'y a pas de champ "episode_trans.number", je suppose que vous voulez dire "episode.id_episode". Je vais voter votre réponse dès que je peux (je n'ai pas assez de réputation pour voter encore) –

2

Je l'ai testé les éléments suivants sur MySQL 4.1 - il retourne votre résultat attendu:

SELECT s.season_number AS season, 
      e.number AS episode, 
      et.name 
    FROM SEASON s 
    JOIN EPISODE e ON e.id_season = s.id_season 
LEFT JOIN EPISODE_TRANS et ON et.id_episode = e.id_episode 
          AND et.id_lang = 1 
    WHERE s.id_serie = 1 
ORDER BY s.season_number, e.number 

En général, lorsque vous utilisez la syntaxe ANSI-92 JOIN vous n eed pour spécifier les critères de jointure dans la clause ON. En MySQL, je sais que ne pas le fournir pour INNER JOINs résulte en une jointure croisée - un produit cartésien.

+0

Merci OMG Ponies, votre réponse était correcte aussi. Je voterai votre réponse dès que possible (je n'ai pas encore assez de réputation pour voter) –