IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

Jointure à partir d'une même table


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Homme Profil pro
    IT in outer space
    Inscrit en
    Novembre 2006
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : IT in outer space

    Informations forums :
    Inscription : Novembre 2006
    Messages : 88
    Points : 96
    Points
    96
    Par défaut Jointure à partir d'une même table
    Bonjour,

    je cherche à réaliser une requête se basant sur des infos de la même table.

    Vous pouvez consulter les images jointes en bas de message.
    En fait la table la plus importante est data (cf. image 1) et elle comprend une colonne idlang qui permet de préciser la langue des données d'un tuple et une colonne id_phrase qui permet d'identifier une phrase dans les différentes langues.

    Ce que je cherche à obtenir, c'est une table qui se présenterait comme sur l'image 4. En gros je souhaite créer un tableau qui sur la même ligne comprend les informations pour les langues qui m'intéressent.

    Pour ça, j'ai essayé plusieurs choses.
    Déjà des jointures mais il existe différents types dont je ne connais pas précisément les différences mais je me suis lancé avec LEFT JOIN.
    Pour le moment j'ai déjà voulu essayer de ne joindre que les données en français et en anglais.
    Voilà ma requête mais apparemment il y aurait un problème de syntaxe. J'ai aussi essayer de mettre des parenthèses autour des SELECT.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT d1.id_phrase, d1.idicon, d1.titre AS tfr, d1.desc AS dfr FROM data AS d1 WHERE idlang=1
    LEFT JOIN
    SELECT d2.id_phrase, d2.titre AS ten, d2.desc AS den FROM data AS d2 WHERE idlang=2
    ON d1.id_phrase=d2.id_phrase
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #1064 - You have an error in your SQL syntax; check the manual that  corresponds to your MySQL server version for the right syntax to use  near 'LEFT JOIN SELECT d2.id_phrase, d2.titre AS ten, d2.desc AS den FROM data AS d2 W'  at line 2
    Alors j'ai créé des vues (phrasefr, phraseen et phrasejp) mais ça ne marche pas mieux.
    Pourquoi ne puis-je pas utiliser les vues dans ce cas ?
    Comment dois-je procéder pour obtenir le résultat voulu ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    phrasefr
    LEFT JOIN
    phraseen
    ON phrasefr.id_phrase=phraseen.id_phrase
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #1064 - You have an error in your SQL syntax; check the manual that  corresponds to your MySQL server version for the right syntax to use  near 'phrasefr LEFT JOIN phraseen ON phrasefr.id_phrase=phraseen.id_phrase' at line 1
    Pourtant d'après la doc la syntaxe est la suivante (entre autres) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    reference_table LEFT [OUTER] JOIN reference_table condition_jointure
    ...
    où reference_table est définie de la manière suivante :                     
     nom_de_table [[AS] alias] [USE INDEX (liste_de_clefs)] [IGNORE INDEX (liste_de_clefs)]
    et condition_jointure est définie comme suit :         
     ON expr_conditionnelle | USING (column_list)
    Merci d'avance.
    Images attachées Images attachées     

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Bonjour,
    La bonne syntaxe est la suivante:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT t1.col1,t1.col2,t2.col1,t2.col2
    FROM Table as t1
    LEFT OUTER JOIN table as t2 on t1.id1 = t2.id2 and LaConditionQuiVaBien
    WHERE t1.colx = 'toto'

    Tatayo

  3. #3
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Si votre nombre de langues est fixe et connu à l'avance, vous pouvez construire un PIVOT :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
      SELECT id_phrase
           , idicon
           , max(case idlang when 1 then titre end) AS tfr
           , max(case idlang when 1 then desc  end) AS dfr
           , max(case idlang when 2 then titre end) AS ten
           , max(case idlang when 2 then desc  end) AS den
           , max(case idlang when 3 then titre end) AS tjp
           , max(case idlang when 3 then desc  end) AS djp
        FROM DATA
       WHERE idlang in (1, 2, 3)
    GROUP BY id_phrase
           , idicon
    ORDER BY id_phrase asc
    Au passage, desc est un mot clef réservé du langage SQL, vous ne devez pas l'utiliser pour nommer une colonne.

  4. #4
    Membre régulier
    Homme Profil pro
    IT in outer space
    Inscrit en
    Novembre 2006
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : IT in outer space

    Informations forums :
    Inscription : Novembre 2006
    Messages : 88
    Points : 96
    Points
    96
    Par défaut
    Bonjour,

    Merci pour vos réponses.

    Au début j'ai eu un peu de mal à adapter la syntaxe de Tatayo mais j'y suis finalement parvenu et ça semble bien marcher.
    Voici la nouvelle requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT t1.id_phrase, t1.idicon, t1.titre AS tfr, t1.descr AS dfr, t2.titre AS ten, t2.descr AS den
    FROM data AS t1
    LEFT  OUTER  JOIN data AS t2 ON t1.id_phrase = t2.id_phrase
    WHERE t1.idlang =1
    AND t2.idlang =2
    Maintenant pour rajouter la colonne JP je fais comment ? Je met ça entre parenthèses et je refais un LEFT OUTER JOIN ou y'a plus efficace ?

    Pour ta requête Waldar, merci de ta participation mais il semble qu'il y aurait une erreur de syntaxe aussi.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #1064 - You have an error in your SQL syntax; check the manual that  corresponds to your MySQL server version for the right syntax to use  near 'DESC  end) AS dfr        , max(case idlang when 2 then titre end) AS ten        ' at line 4
    Je ne comprends pas bien sa syntaxe mais je trouve étrange qu'il s'accroche à la ligne 4 alors que les précédentes lignes sont pareilles...
    Rectification : ça marche aussi.
    J'ai modifié le nom de colonne desc en descr pour éviter l’ambiguïté avec le mot clé DESC et après avoir mis à jour la requête et testé ça marche très bien.

    Merci à vous deux. Va falloir que je comprenne ta syntaxe Waldar.
    Est-ce qu'un bloc case se termine par end en SQL ?
    Par contre pour moi max() c'était juste pour trouver le maximum parmi des nombres... J'arrive pas trop à comprendre son utilisation ici.

    La question est résolue mais j'aimerais bien avoir une explication dessus. Alors je mettrais à jour le titre du topic.

    Encore merci à vous.

    EDIT:
    J'ai réussi avec la syntaxe de Tatayo en modifiant comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT t1.id_phrase, t1.idicon, t1.titre AS tfr, t1.descr AS dfr, t2.titre AS ten, t2.descr AS den, t3.titre AS tjp, t3.descr AS djp
    FROM data AS t1
    LEFT OUTER JOIN data AS t2
    ON t1.id_phrase=t2.id_phrase
    LEFT OUTER JOIN data as t3
    ON t1.id_phrase=t3.id_phrase
    WHERE t1.idlang=1 AND t2.idlang=2 AND t3.idlang=3

  5. #5
    Membre actif
    Inscrit en
    Janvier 2012
    Messages
    145
    Détails du profil
    Informations forums :
    Inscription : Janvier 2012
    Messages : 145
    Points : 226
    Points
    226
    Par défaut
    Pour la syntaxe des 2 types de CASE, tu peux la trouver à http://sqlpro.developpez.com/cours/sqlaz/select/#L7 .

    Pour les colonnes utilisant des mots-clés réservés, tu peux en général utiliser les crochets, ce qui dans ton cas donnerait [DESC]. Mais c'est une mauvaise pratique et il vaut mieux utiliser des noms non-réservés.

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT t1.id_phrase, t1.idicon, t1.titre AS tfr, t1.descr AS dfr, t2.titre AS ten, t2.descr AS den
    FROM DATA AS t1
    LEFT  OUTER  JOIN DATA AS t2 ON t1.id_phrase = t2.id_phrase
    WHERE t1.idlang =1
    AND t2.idlang =2
    Attention, en mettant une condition sur T2 dans le where, tu changes la jointure externe en jointure interne. Cette condition devrait se trouver dans la jointure:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT t1.id_phrase, t1.idicon, t1.titre AS tfr, t1.descr AS dfr, t2.titre AS ten, t2.descr AS den
    FROM DATA AS t1
    LEFT  OUTER  JOIN DATA AS t2 ON t1.id_phrase = t2.id_phrase AND t2.idlang =2
    WHERE t1.idlang =1

    Tatayo.

  7. #7
    Membre régulier
    Homme Profil pro
    IT in outer space
    Inscrit en
    Novembre 2006
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : IT in outer space

    Informations forums :
    Inscription : Novembre 2006
    Messages : 88
    Points : 96
    Points
    96
    Par défaut
    Je sais même pas la différence entre jointure externe et interne.
    Ni même ce qu'une jointure naturelle, croisée et cie... J'ai juste rencontré ces termes en lisant un peu la doc.
    En tout cas merci pour la remarque.
    Mine de rien c'est complexe MySQL quand on veut maitriser.

    KookieMonster. Merci pour le tuto/doc. Ça va bien plus loin que mes cours ou mes bouquin de PHP/MySQL.
    Bon allez zou !
    Question résolue.

    PS : C'est quoi ce délire ?!
    Je ne peux plus éditer le premier message et je ne vois pas de bouton pour mettre la question en résolue. Ça se passe comment ?
    Re : Ça y est j'ai trouvé. C'est pas une super idée de le mettre tout en bas je trouve...

  8. #8
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Les éditions de message sont restreinte dans le temps. Ca évite que des personnes suppriment le contenu des postes une fois le problème résolu.

    Pour les jointures : http://sqlpro.developpez.com/cours/sqlaz/jointures/

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [AC-2003] Jointure externe sur une même table
    Par jeff69 dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 14/09/2009, 22h11
  2. Jointures multiples sur une même table
    Par hjhjhj dans le forum Langage SQL
    Réponses: 10
    Dernier message: 08/05/2009, 16h48
  3. Jointure entre deux champs d'une même table
    Par oubli dans le forum Requêtes
    Réponses: 8
    Dernier message: 11/12/2007, 16h20
  4. jointure sur des lignes d'une même table
    Par elsa_dach dans le forum Langage SQL
    Réponses: 3
    Dernier message: 19/01/2007, 12h08
  5. jointure sur une même table
    Par guillaumeVb6 dans le forum Langage SQL
    Réponses: 7
    Dernier message: 06/09/2004, 15h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo