[RESOLU] [MySQL] Jointures sur 3 tables

Jointures sur 3 tables [RESOLU] [MySQL] - SQL/NoSQL - Programmation

Marsh Posté le 27-01-2011 à 14:28:12    

Bonjour à tous,
 
Question de logique, j'arrive pas à mettre sous forme de requete mon besoin (et pourtant j'ai déjà pas mal de lignes de code à mon actif...)  
Voici un exemple de la situation que j'ai a gérer.
(Le but de cet exemple étant simplement que je comprenne le mécanisme qui me permettra de construire la requete de mon cas réel)
 
Soit:3 tables:

TBL1, 2 colonnes: ID1 et DATA1
TBL2, 2 colonnes: ID2 et DATA2
TBL3, 2 colonnes: ID3 et DATA3


 
Des données:


TBL1:
ID1 DATA1
 1    11
 2    12
 3    13
 
TBL2:
ID2 DATA2
 1    21
 3    23
 4    24
 
TBL3:
ID3;DATA3
 2    32
 4    34
 5    35


 
Je cherche la requete permettant d'avoir ce résultat:


ID  DATA1  DATA2  DATA3
1   11     21     NULL
2   12     NULL   34
3   13     23     NULL
4   NULL   24     34
5   NULL   NULL   35


 
On a donc un ID commun aux trois tables et les valeurs correspondantes (si existantes) mises sur chaque ligne.
l'ID est Unique pour chaque table, c'est une des contraintes.
 
Ca ne fait "que" 2 jours que je m'arrache les cheveux avec cette requete... et je n'avance pas d'un poil.
Si quelqu'un à une idée...
 
Merci d'avance,
Gaël


Message édité par mtregael le 27-01-2011 à 16:13:07
Reply

Marsh Posté le 27-01-2011 à 14:28:12   

Reply

Marsh Posté le 27-01-2011 à 15:01:39    

Plutôt que de t'arracher les cheveux, ouvre pour la premiere fois de ta vie un doc sur SQL à la section LEFT JOIN :sarcastic:
 
Je pense pas qu'on puisse faire plus basique


Message édité par smaragdus le 27-01-2011 à 15:02:27
Reply

Marsh Posté le 27-01-2011 à 15:12:39    

Merci, mais je n'ai pas besoin de tes conseils pour ouvrir le doc mysql.  
 
Dans les différentes requetes que j'ai tenté de construire, soit il manque des données, soit les lignes sont doublées, soit etc... m'enfin y'a un truc qui va pas.
 
C'est peut-être justement parce que c'est trop simple que je n'arrive pas à le coder... je dois louper une subtilité du JOIN !
 
Du haut de ta supériorité, vu que cela est aussi simple pour toi, donne moi au moins des pistes... je n'ai jamais demandé la requete clé en main.

Reply

Marsh Posté le 27-01-2011 à 15:15:52    

from table1 left join table2 on table1.id = table2.id

 

et les jointures font effectivement partis des bases en SGBD


Message édité par flo850 le 27-01-2011 à 15:33:38
Reply

Marsh Posté le 27-01-2011 à 15:21:34    

Oui... ok... je connais le JOIN.
 

select * from tbl1 left join tbl2 on tbl1.ID1=tbl2.ID2


 
ca me donne:


ID1 DT1 ID2 DT2
1 11 1 21
2 12  
3 13 3 23


Mais ça, ça ne me sort que les ligne de table2 qui sont dans table1 !
les lignes de table2 qui ne sont pas dans table1 ne sont pas là...
Voir mon tableau d'exemple.
Et puis pour joindre avec table3...

Reply

Marsh Posté le 27-01-2011 à 15:27:07    

Je ne suis pas un expert en SQL, mais il y a au moins la requête suivante qui répond à ton problème. C'est vraiment brut de fonderie, il y a sûrement moyen d'optimiser, mais mes connaissances s'arrêtent là.
 

Code :
  1. select if(isnull(ID1), if (isnull(ID2) , ID3 , ID2) , ID1) as id , DATA1 , DATA2, DATA3
  2. from TBL1 left join TBL2 on ID1 = ID2 left join TBL3 on ID1 = ID3
  3. union
  4. select if(isnull(ID1), if (isnull(ID2) , ID3 , ID2) , ID1) as id , DATA1 , DATA2, DATA3
  5. from TBL2 left join TBL1 on ID2 = ID1 left join TBL3 on ID2 = ID3
  6. union
  7. select if(isnull(ID1), if (isnull(ID2) , ID3 , ID2) , ID1) as id , DATA1 , DATA2, DATA3
  8. from TBL3 left join TBL1 on ID3 = ID1 left join TBL3 on ID3 = ID2


 
Si quelqu'un sait comment optimiser tout ca, ca m'intéresse !

Reply

Marsh Posté le 27-01-2011 à 15:31:54    

shaoyin: c'est une piste interessante... mais elle ne fonctionne pas car il faut nommer les tables.  
Je vais essayer de partir sur cette piste. Je pensais qu'on pouvais s'en sortir simplement avec des jointures... je ne voyais pas le besoin de mettre des conditions.

Reply

Marsh Posté le 27-01-2011 à 15:35:09    

mtregael a écrit :

Oui... ok... je connais le JOIN.

 

select * from tbl1 left join tbl2 on tbl1.ID1=tbl2.ID2

 

ca me donne:


ID1 DT1 ID2 DT2
1 11 1 21
2 12  
3 13 3 23


Mais ça, ça ne me sort que les ligne de table2 qui sont dans table1 !
les lignes de table2 qui ne sont pas dans table1 ne sont pas là...
Voir mon tableau d'exemple.
Et puis pour joindre avec table3...

 

full outer join un des quatres types de jointures, avec inner,left et right


Message édité par flo850 le 27-01-2011 à 15:35:19
Reply

Marsh Posté le 27-01-2011 à 15:37:47    

Dans certains SGBD, il y a FULL OUTER JOIN mais cela n'existe pas en mysql, essaye de te rencarder là dessus pour voir comment le simuler en mysql
mais tu es obligé de passer par un UNION


Message édité par antac le 27-01-2011 à 15:38:47
Reply

Marsh Posté le 27-01-2011 à 15:41:06    

Oui, j'ai peut-être oublié de préfixer les champs par les noms de table... Au moins, ca facilite la lecture !
 
Le problème, c'est que dans ton résultat, l'identifiant est commun. Il faut donc afficher celui qui n'est pas null, d'ou l'utilisation des conditions.

Reply

Marsh Posté le 27-01-2011 à 15:41:06   

Reply

Marsh Posté le 27-01-2011 à 15:43:46    

Ok... j'allais effectivement répondre à flo850 que le full outer join n'existe pas nativement en mysql. C'est effectivement le type de jointure dont j'ai besoin pour mon cas.
 
J'ai tenté de le faire avec des unions, mais imbriquer les 3 tables me fait une requete de psychopate pour pas grand chose et je n'arrive pas au bout.
 
Là, je pensais partir d'une construction de la liste de mes ID pour faire un LEFT JOIN sur les autres tables, mais je ne vois pas comment avoir sur la même ligne les valeurs des différentes table pour un même ID... (enfin, moi je me comprend... mais c'est pas simple à expliquer).

Reply

Marsh Posté le 27-01-2011 à 15:44:34    

effectivement, j'avais zappé le fait quemysql n'a pas de full outer join
ceci dit google peut t'aider avec les bons termes : http://www.xaprb.com/blog/2006/05/ [...] -in-mysql/

Reply

Marsh Posté le 27-01-2011 à 15:47:34    

Code :
  1. select id1 as id, data1, data2, data3 from tbl1 left join tbl2 on id1=id2 left join tbl3 on id3=id1
  2. union distinct
  3. select id2 as id, data1, data2, data3 from tbl2 left join tbl1 on id1=id2 left join tbl3 on id3=id2
  4. union distinct
  5. select id3 as id, data1, data2, data3 from tbl3 left join tbl2 on id3=id2 left join tbl1 on id3=id1


 
edit : union distinct put***  [:zytrasnif]


Message édité par smaragdus le 27-01-2011 à 15:53:52
Reply

Marsh Posté le 27-01-2011 à 15:55:31    

Ah oui, avec mes conditions je me suis vraiment emm...

Reply

Marsh Posté le 27-01-2011 à 15:57:51    

Ca n'a rien à voir mais à propos de condition if (isnull(....  la fonction coalesce() est des fois très utile :
 
 
mysql> SELECT COALESCE(NULL,NULL,NULL,NULL,1,2,3);
        -> 1


Message édité par smaragdus le 27-01-2011 à 15:58:09
Reply

Marsh Posté le 27-01-2011 à 16:12:35    

antac: Merci pour le QR Code... j'ai un peu l'air con maintenant !!!
 
smaragdus: je vais virer zinzin car je suis certain de l'avoir essayé ça et ca ne m'avait pas retourné le résultat attendu. Et maintenant c'est ok... là je comprend pas.  
J'avais du mélanger quelquechose dans ma requete.
 
Par contre, le "distinct" est facultatif: "The optional DISTINCT keyword has no effect other than the default because it also specifies duplicate-row removal". D'ailleurs, le résultat est le même sans.
 
En tous cas, merci à tous pour votre aide.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed