Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 8 sur 8
  1. #1
    Membre du Club
    Opérateur
    Inscrit en
    novembre 2006
    Messages
    76
    Détails du profil
    Informations professionnelles :
    Activité : Opérateur

    Informations forums :
    Inscription : novembre 2006
    Messages : 76
    Points : 55
    Points
    55

    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 :
    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 :
    #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 :
    1
    2
    3
    4
    phrasefr
    LEFT JOIN
    phraseen
    ON phrasefr.id_phrase=phraseen.id_phrase
    Code :
    #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 :
    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 Confirmé Sénior
    Homme Profil pro
    Développeur Freelance
    Inscrit en
    janvier 2009
    Messages
    2 297
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Freelance

    Informations forums :
    Inscription : janvier 2009
    Messages : 2 297
    Points : 4 161
    Points
    4 161

    Par défaut

    Bonjour,
    La bonne syntaxe est la suivante:
    Code SQL :
    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

    Homme Profil pro Fabien
    Ingénieur d'études en décisionnel
    Inscrit en
    septembre 2008
    Messages
    6 835
    Détails du profil
    Informations personnelles :
    Nom : Homme Fabien
    Âge : 36
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur d'études en décisionnel
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : septembre 2008
    Messages : 6 835
    Points : 13 511
    Points
    13 511

    Par défaut

    Si votre nombre de langues est fixe et connu à l'avance, vous pouvez construire un PIVOT :
    Code :
    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 du Club
    Opérateur
    Inscrit en
    novembre 2006
    Messages
    76
    Détails du profil
    Informations professionnelles :
    Activité : Opérateur

    Informations forums :
    Inscription : novembre 2006
    Messages : 76
    Points : 55
    Points
    55

    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 :
    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 :
    #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 :
    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 confirmé
    Inscrit en
    janvier 2012
    Messages
    145
    Détails du profil
    Informations forums :
    Inscription : janvier 2012
    Messages : 145
    Points : 201
    Points
    201

    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 Confirmé Sénior
    Homme Profil pro
    Développeur Freelance
    Inscrit en
    janvier 2009
    Messages
    2 297
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Freelance

    Informations forums :
    Inscription : janvier 2009
    Messages : 2 297
    Points : 4 161
    Points
    4 161

    Par défaut

    Code SQL :
    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 :
    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 du Club
    Opérateur
    Inscrit en
    novembre 2006
    Messages
    76
    Détails du profil
    Informations professionnelles :
    Activité : Opérateur

    Informations forums :
    Inscription : novembre 2006
    Messages : 76
    Points : 55
    Points
    55

    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é Sénior
    Homme Profil pro
    Inscrit en
    mai 2002
    Messages
    3 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : mai 2002
    Messages : 3 037
    Points : 4 613
    Points
    4 613

    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.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •