Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 30/01/2012, 23h41   #1
Membre du Club
 
Padawan Informaticien en recherche d'emploi (Bac+3 Administration des Systèmes et des Réseaux)
Inscription : novembre 2006
Messages : 67
Détails du profil
Informations professionnelles :
Activité : Padawan Informaticien en recherche d'emploi (Bac+3 Administration des Systèmes et des Réseaux)

Informations forums :
Inscription : novembre 2006
Messages : 67
Points : 51
Points : 51
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
Type de fichier : png jointure.data.sql.png (9,8 Ko, 5 affichages)
Type de fichier : png jointure.icons.sql.png (2,3 Ko, 3 affichages)
Type de fichier : png jointure.langues.sql.png (2,7 Ko, 3 affichages)
Type de fichier : png jointure.objectif.sql.png (5,1 Ko, 4 affichages)
Pasokoniidesuka est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/01/2012, 08h26   #2
Membre Expert
 
Homme
Responsable de service informatique
Inscription : janvier 2009
Messages : 1 099
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 38
Localisation : France

Informations professionnelles :
Activité : Responsable de service informatique
Secteur : Boutique - Magasin

Informations forums :
Inscription : janvier 2009
Messages : 1 099
Points : 1 922
Points : 1 922
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
tatayo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/01/2012, 11h54   #3
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 686
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 686
Points : 10 435
Points : 10 435
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
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.
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/02/2012, 17h49   #4
Membre du Club
 
Padawan Informaticien en recherche d'emploi (Bac+3 Administration des Systèmes et des Réseaux)
Inscription : novembre 2006
Messages : 67
Détails du profil
Informations professionnelles :
Activité : Padawan Informaticien en recherche d'emploi (Bac+3 Administration des Systèmes et des Réseaux)

Informations forums :
Inscription : novembre 2006
Messages : 67
Points : 51
Points : 51
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
Pasokoniidesuka est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/02/2012, 18h44   #5
Membre actif
 
Inscription : janvier 2012
Messages : 117
Détails du profil
Informations forums :
Inscription : janvier 2012
Messages : 117
Points : 173
Points : 173
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.
KookieMonster est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/02/2012, 22h35   #6
Membre Expert
 
Homme
Responsable de service informatique
Inscription : janvier 2009
Messages : 1 099
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 38
Localisation : France

Informations professionnelles :
Activité : Responsable de service informatique
Secteur : Boutique - Magasin

Informations forums :
Inscription : janvier 2009
Messages : 1 099
Points : 1 922
Points : 1 922
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.
tatayo est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 06/02/2012, 23h50   #7
Membre du Club
 
Padawan Informaticien en recherche d'emploi (Bac+3 Administration des Systèmes et des Réseaux)
Inscription : novembre 2006
Messages : 67
Détails du profil
Informations professionnelles :
Activité : Padawan Informaticien en recherche d'emploi (Bac+3 Administration des Systèmes et des Réseaux)

Informations forums :
Inscription : novembre 2006
Messages : 67
Points : 51
Points : 51
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...
Pasokoniidesuka est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 08h59   #8
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 655
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 655
Points : 2 657
Points : 2 657
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/
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 07h07.


 
 
 
 
Partenaires

Hébergement Web