[MySQL] Presenter des donnees en ligne en colonne

Presenter des donnees en ligne en colonne [MySQL] - SQL/NoSQL - Programmation

Marsh Posté le 05-09-2010 à 10:06:40    

Bonjour,
 
J'ai une question sur un probleme que j'imagine classique mais que je suis bien en peine de regler.
 
Je dispose d'une liste d'enfants (id, nom etc...) et d'un liste de responsables legaux (id, nom) le tout relie par une table avoir_comme (id_enfant, id_resplegal).
 
Je souhaite afficher une liste des enfants avec tous leurs responsables legaux.
 
La solution la plus simple me permet d'afficher une ligne par responsable legal :
nomEnfant, prenomEnfant, nomRespLegal, PrenomResponsableLegal
DURAND;PIERRE;DURAND;Papa
DURAND;PIERRE;DURAND;Maman
etc...
 
Cet affichage ne me convient par car j'aimerais afficher une liste de ce type
 
nomEnfant, prenomEnfant, nomRespLegal1, PrenomResponsableLegal1, nomRespLegal2, PrenomResponsableLegal2
 
 
Connaitriez vous la maniere de faire ?
 
Merci d'avance
 
v.

Reply

Marsh Posté le 05-09-2010 à 10:06:40   

Reply

Marsh Posté le 05-09-2010 à 10:16:53    

le plus simple est de faire un traitement ensuite dans un langage comme php ou asp  

Reply

Marsh Posté le 05-09-2010 à 11:43:47    

C'est sur mais :
1. je n'ai pas trop le choix car je cree un fichier excel a partir d'une requete et j'aimerais conserver ce principe
2. je suis intimement persuade que c'est faisable en SQL (pivot ou autre) mais je n'y arrive pas
 
a+
 
v.

Reply

Marsh Posté le 05-09-2010 à 13:37:44    

oui , mais ça va etre sale ( group_concat )

Reply

Marsh Posté le 05-09-2010 à 20:55:30    

Je suis preneur d'une solution meme sale.
Je ne connais pas group_contact, de quoi s'agit il ?
 
v.

Reply

Marsh Posté le 06-09-2010 à 10:25:11    

google + RTFM :/


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 06-09-2010 à 11:58:22    

Oui ben ca c'est fait mais j'ai pas tout capté !
 
D'ou l'intéret d'une question sur un forum...
 
v.

Reply

Marsh Posté le 06-09-2010 à 13:13:45    

Ces 2 sites sont quand même explicites sur ce que fait group_concat, non?
Site officiel : http://dev.mysql.com/doc/refman/5. [...] tions.html
 
Exemple : http://blog.maiis.ch/2008/09/30/my [...] up_concat/


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 06-09-2010 à 16:06:15    

ouaip !
effectivement mais ca ne correspond pas a mon besoin.
 
N'existe t'il pas en sql un moyen de convertir des infos de lignes en colonnes ?
Je remarque sur le net que ca semble etre une question recurrente mais je ne vois pas de reponse qui semble viable.
 
Juste pour info, je resume et precise mon besoin
 
table1
idtable1; nom
1;toto
2;titi
3;tutu
 
table2
idtable2;libelle
1;test1
2;test2;
3;test3
 
table3
idtable1;idtable2
1;1
1;2
2;1
2;3
 
si j'execute cette requete "select idtable1; nom; libelle from table1, table2, table3 where table1.idtable1=1 and table1.idtable1 = table3.idtable1 and table3.idtable2 = table2.idtable2", j'obtiens :
idtable1;nom; libelle
1;toto;test1
1;toto;test2
 
Tout cela me parait normal mais ne correspond pas a l'affichage souhaite.
 
J'aimerais moi qua ma requete sql me renvoie quelque chose qui ressemble a ca :
 
idtable1;nom;libelle;libelle
1;toto;test1;test2
 
Qualqu'un saurait il modifier la requete ci-dessus pour gerer cela ?
 
Merci d'avance
 
v.

Reply

Marsh Posté le 07-09-2010 à 09:56:45    

Donc utilises group_conctat, bon sang!  :fou: C'est fait pour ça. Tu ne sais pas lire une doc ou quoi :??:

Message cité 1 fois
Message édité par rufo le 07-09-2010 à 09:57:27

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 07-09-2010 à 09:56:45   

Reply

Marsh Posté le 07-09-2010 à 10:57:31    

rufo a écrit :

Donc utilises group_conctat, bon sang!  :fou: C'est fait pour ça. Tu ne sais pas lire une doc ou quoi :??:


 
Ben manifestement non, je ne sais pas !
Je ne veux pas concatener du texte dans un champ, je veux recuperer plusieurs champs !
 
A moins qu'effectivement, je ne sache pas lire, ce n'est pas l'usage de group_concat.
 
Note que si c'est si evident, je ne suis pas contre un petit exemple...
 
v.

Reply

Marsh Posté le 07-09-2010 à 12:06:17    

select idEnfant, GROUP_CONCAT( CONCAT (nomRespLegal, PrenomResponsableLegal)  )  
FROM enfants LEFT JOIN responsableLegal ON enfants.id = responsableLegal.idenfant
GROUP BY enfants  
 
Si par contre tu veux avoir un nombre variable de colonnes dans ton resultats, c'est mort , a moins que tu ne connaisses le nombre maxi de responsables, auxquel cas, c'ets juste sale  
 
exemple avec 2 responsables légaux au maxi :  
 
select idEnfant, resp1.nomRespLegal, resp1.PrenomResponsableLegal, resp2.nomRespLegal, resp2.PrenomResponsableLegal,
FROM enfants  
LEFT JOIN responsableLegal resp1 ON enfants.id = responsableLegal.idenfant
LEFT JOIN responsableLegal resp2 ON enfants.id = responsableLegal.idenfant AND resp1.id != resp2.id

Reply

Marsh Posté le 07-09-2010 à 12:11:31    

Vue que tu veux générer un fichier excel, je suppose que c'est au format csv? Donc, dans ce cas, non, ce ne sont pas (forcément) des champs que tu veux récupérer, mais au final une chaîne de caractères au format csv. Et la group_concat te le permet via le paramètre SEPARATOR qui indique la chaîne à insérer pour séparer les différentes valeurs (; ou , par ex).


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 07-09-2010 à 12:34:34    

flo850 a écrit :

select idEnfant, GROUP_CONCAT( CONCAT (nomRespLegal, PrenomResponsableLegal)  )  
FROM enfants LEFT JOIN responsableLegal ON enfants.id = responsableLegal.idenfant
GROUP BY enfants  
 
Si par contre tu veux avoir un nombre variable de colonnes dans ton resultats, c'est mort , a moins que tu ne connaisses le nombre maxi de responsables, auxquel cas, c'ets juste sale  
 
exemple avec 2 responsables légaux au maxi :  
 
select idEnfant, resp1.nomRespLegal, resp1.PrenomResponsableLegal, resp2.nomRespLegal, resp2.PrenomResponsableLegal,
FROM enfants  
LEFT JOIN responsableLegal resp1 ON enfants.id = responsableLegal.idenfant
LEFT JOIN responsableLegal resp2 ON enfants.id = responsableLegal.idenfant AND resp1.id != resp2.id


 
 
La methode sale me convient bien mais je dispose entre les deux tables enfant et responsablelegal d'une table avoir_comme(id_enfant, id_resplegal).
 
Sais-tu comment je peux modifier ta requete pour que cela fonctionne ?
 
v.

Reply

Marsh Posté le 07-09-2010 à 14:01:48    

oui, je sais :d

Code :
  1. SELECT idEnfant, resp1.nomRespLegal, resp1.PrenomResponsableLegal, resp2.nomRespLegal, resp2.PrenomResponsableLegal,
  2.  FROM enfants  
  3.   LEFT JOIN avoir_comm ac1 ON enfant.id = ac1 .id_enfant
  4.   LEFT JOIN responsableLegal resp1 ON ac1 . id_resplegal = responsableLegal.idenfant
  5.  
  6.   LEFT JOIN avoir_comm ac2 ON enfant.id = ac2 .id_enfant
  7.   LEFT JOIN responsableLegal resp1 ON ac2 . id_resplegal = responsableLegal.idenfant   AND resp1.id != resp2.id
 

ceci dit, si tu as besoin d'un csv, group_concat fait le boulot, plus facilement


Message édité par flo850 le 07-09-2010 à 14:02:07
Reply

Marsh Posté le 07-09-2010 à 14:30:37    

si t'as plus de deux représentants légaux par enfant, t'es dans la merde...   :o  
 
Donc t'es parti pour:
 
1. faire des left join suffisants pour joindre tous les représentants (combien max? 2, 10, 100? Bonjour la performance)  :pt1cable:  
2. utiliser group_concat (propre à MySQL, donc pas de portabilité de ton code)  :non:  
3. utiliser le language de programmation qui te fera ce que tu dois très facilement  :jap:  
 

Reply

Marsh Posté le 07-09-2010 à 14:53:25    

Apres adaptation et essai de cette requete j'ai droit a un resultat semblable a ceci
 
id_enfant;nom_resp1;prenom_resp1;nom_resp2;prenom_resp2
1;durand;jerome;NULL;NULL
1;durand;jerome;durand;nathalie
1;durand;nathalie;durand;jerome
 
Autant je peux comprendre les deux dernieres lignes (mais je ne sais pas comment filtrer), autant je ne comprends pas la ligne avec les NULL...
 
Une idee ?
 
v.
 
Edit : je n'avais pas vu mais j'ai aussi une 4eme ligne, de la forme  
1;durand;nathalie;NULL;NULL


Message édité par vonm le 07-09-2010 à 14:54:58
Reply

Marsh Posté le 07-09-2010 à 14:59:32    

faire de inner join au lien de left join. autre solution, faire un filtrage avec la clause having.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 07-09-2010 à 15:08:36    

SELECT idEnfant, resp1.nomRespLegal, resp1.PrenomResponsableLegal, resp2.nomRespLegal, resp2.PrenomResponsableLegal,  
  FROM enfants  
   LEFT JOIN avoir_comm ac1 ON enfant.id = ac1 .id_enfant  
   LEFT JOIN responsableLegal resp1 ON ac1 . id_resplegal = responsableLegal.idenfant  
 
   LEFT JOIN avoir_comm ac2 ON enfant.id = ac2 .id_enfant  
   LEFT JOIN responsableLegal resp1 ON ac2 . id_resplegal = responsableLegal.idenfant   AND resp1.id < resp2.id
 
(je remplace le != par < pour etre sur qu'on ne puisse pas permuter les représentants)
Si tu remplaces LEFT JOIN par INER JOIN ca ne marchera plus dans le cas d'enfant qui n'ont qu'un seul représentant légal
Cette requete par contre marche mal avec  les enfants qui ont plus de 2 représentants

Reply

Marsh Posté le 07-09-2010 à 15:09:22    

jeff@be a écrit :

si t'as plus de deux représentants légaux par enfant, t'es dans la merde...   :o  
 
Donc t'es parti pour:
 
1. faire des left join suffisants pour joindre tous les représentants (combien max? 2, 10, 100? Bonjour la performance)  :pt1cable:  
2. utiliser group_concat (propre à MySQL, donc pas de portabilité de ton code)  :non:  
3. utiliser le language de programmation qui te fera ce que tu dois très facilement  :jap:  
 


 
Plus ca va et plus je me dis que tu as raison et que je devrais modifier ma classe PHP plutot que de ma lancer dans du sql fumeux que je ne maitrise pas.
 
Je vais regarder ca.
 
Merci a vous tous pour vos reponses.
 
v.

Reply

Marsh Posté le 07-09-2010 à 15:09:57    

clairement, c'est le genre de truc faisaable en moins de 10 lignes en php

Reply

Marsh Posté le 07-09-2010 à 15:28:07    

Ben oui mais j'ai voulu jouer le faineant en utilisant un truc tout fait depuis le debut et je pense que j'aurais mieux fait de m'abstenir...
 
encore merci
 
v.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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