[Access] Regrouper plusieurs résultats d'1 requête sur 1 seule ligne?

Regrouper plusieurs résultats d'1 requête sur 1 seule ligne? [Access] - SQL/NoSQL - Programmation

Marsh Posté le 25-02-2009 à 08:19:42    

Bonjour,
 
Je travaille actuellement sur un projet pour lequel je dois exporter une base de donnée de contacts vers un fichier Excel pour une migration ultérieure vers un autre système.
 
Les infos que je dois exporter sont contenues dans une BD Access avec plusieurs tables. J'ai donc créé des requêtes pour pouvoir regrouper les infos dont j'ai besoin, le but étant d’avoir une base de contacts sous Excel avec toutes les infos (venant de plusieurs tables) pour chacun des contacts.
 
Au final, j'aimerais avoir un tableau qui contiendrait les champs suivants:

Citation :

Nom     Info1     Info2     Info3     Info4     [...]     Options


 
 
Infon pouvant être un numéro de téléphone, un e-mail, une adresse etc...    
J'ai donc créé une requete avec tous ces champs que l'on va appeler "Requête Principale"
 
Par contre, pour la colonne options de cette requete, qui fait appel à une table spécifique (contenant seulement Nom du Contact et Option) il y a plusieurs options possibles pour un même contact, ce qui donne une table comme suit :
 

Citation :

Nom                      Options
Contact1             OptionA
Contact2             OptionA
Contact1             OptionB
Contact2             OptionY
Contact3             OptionZ
Etc.


Cette table contient donc toutes les options mélangées. Lorsque je veux ajouter le champs option directement dans ma Requete Principale, j'obtient plusieurs lignes pour un même contact, chaque ligne contenant l'une des options associée au contact (normal). Ce qui donne:

Citation :

Nom             Info1        Info2       Info3     Info4        [...]     Options
Contact1     EMail1    Adresse1    Tel1     Fax1       [...]    OptionA
Contact1     EMail1    Adresse1    Tel1     Fax1       [...]    OptionB
Contact2     EMail2    Adresse2    Tel2     Fax2       [...]    OptionA
Contact2     EMail2    Adresse2    Tel2     Fax2       [...]    OptionY
etc...


 
 
Je voudrais n’avoir qu’une ligne par contact dans les résultats donc je voudrais faire une sorte de concaténation dans la même colonne avec un séparateur (si possible au choix) du genre :

Citation :

Nom              [...]      Options
Contact1      [...]     OptionA,OptionB
Contact2      [...]     OptionA,OptionY
Contact3      [...]     OptionZ


 
Sur la forme, je suis pas difficile, on peut intégrer directement l'astuce dans la requete principale, ou passer par une requête intermédaire s'il faut puis récupérer les résultats dans la Requete Principale ensuite :)  
 
Pour quelqu’un qui maitrise les DB et Access, ça peut paraître con (ou pas) mais après un peu de prise de tête, de recherches dans Google et dans ma mémoire, j’ai pas trouvé, ou juste des pistes (concaténation, groupe by, macro/module, modif dans la requete SQL…) et au final, j'en ressors avec rien du tout :( Je dois préciser que je n'ai aucun connaissance en programmation, j'arrive juste à bidouiller dans la limite de mes connaissances (acquises sur le tas selon mes besoins).
 
Merci d'avance à qui pourra m'aider :)


Message édité par Mariton le 25-02-2009 à 08:57:02
Reply

Marsh Posté le 25-02-2009 à 08:19:42   

Reply

Marsh Posté le 25-02-2009 à 11:09:54    

j'ai trouvé ça ... à tester ;-)
=>
http://www.sqlfr.com/codes/ACCESS- [...] 32792.aspx


---------------
il n'y a pas que le VTT dans la vie, il y a le Snowboard aussi ...
Reply

Marsh Posté le 26-02-2009 à 09:01:22    

Merci pour ta réponse :)

 

La solution qui est décrite donne un résultat un peu différent de ce que j'aimerais avoir. Le tuto décrit comment classer les données dans un tableau croisé alors que moi, je voudrais juste combiner plusieurs résultats dans une même cellule (au lieu de plusieurs lignes).

 

Quelqu'un connaît-il un astuce?

 

Merci ;)


Message édité par Mariton le 26-02-2009 à 09:01:38
Reply

Marsh Posté le 26-02-2009 à 09:30:02    

ta première table, elle a cette structure pourrie uniquement ?
 
comment tu regroupes les emails, les téléphones, etc. ?
 
si tu as un critère de regroupement, à coup d'auto-jointures tu peux parfaitement faire ton truc en SQL standard.

Reply

Marsh Posté le 26-02-2009 à 09:58:05    

La table principale possède les infos basiques pour chaque contact (nom, adresse, e-mail etc...).
J'ai d'autres tables qui contiennent des infos internes, que je dois associer avec chaque contact (via la requête, le champ commun étant l'id du contact)... et y'a cette fameuse table "Options" avec 2 champs: l'id du contact et l'option (qui est elle insérée à partir d'une liste de choix venant d'une autre table). Pour un même id de contact, je peux trouver plusieurs lignes avec des options différentes (jusqu'à une dizaine d'options différentes) et donc si j'ajoute la table et le champ option à ma requête principal, il m'affiche autant de lignes que d'options pour le même contact.

 

Je voudrais ne conserver qu'une ligne par contact et une colonne "Options", laquelle contiendrait toutes les options de chaque contact, séparées par ',' ou ';' par exemple.

 

Est-ce que ça répond à ta question?

 

Et si jamais ça peut-être fait en SQL standard, puisque je suis pas spécialiste et que je n'ai pas trouvé seul (même si c'est très con), j'aimerais bien un petit coup de main pour cette manip :)

 

Merci :jap:


Message édité par Mariton le 26-02-2009 à 10:02:05
Reply

Marsh Posté le 26-02-2009 à 13:50:40    

la structure de ta table options est à revoir. tu ne pourras pas faire ça avec access.
 
seul mysql a une fonction "group_concat()" qui permet de faire ça, et c'est pas standard du tout. en plus, tes "options" ne seront pas triées, donc à mon avis c'est de toute façon complètement naze comme résultat ce que tu vas avoir, tout sera mélangé)

Reply

Marsh Posté le 03-03-2009 à 04:31:44    

Merci pour ta réponse!
 
Dommage, je pensais qu'on pouvait tout de même faire un semblant de quelque chose malgré la structure complexe :(
 
Je vais donc tenter de contourner le problème via Excel avec une fonction type concatvlookup ;)
 
Merci encore pour votre aide :jap:

Reply

Marsh Posté le 27-05-2016 à 20:14:04    

Il n'est jamais trop tard pour bien faire alors un exemple.  
 
Soit  
RecordID Order Stage Person StageDate
1 1 A1 Allan 01-May
2 1 Brody 04-May
3 1 A2 Cash 05-May
4 2 A1 Neff 08-May
5 2 A2 Dub 08-May
6 2 A3 Duff 09-May
7 3 A1 Pat 15-May
8 3 Allan 20-Jun
9 3 A2 Brody 21-Jun
10 4 A1 Duff 03-May
11 4 Brody 05-May
12 4 A2 Duff 09-May
13 4 A3 Cash 10-May
 
On veut obtenir  
 
Order StagePersonDateSeries
1 A1 Allan 01-May A2 Cash 05-May
2 A1 Neff 08-May A2 Dub 08-May A3 Duff 09-May
3 A1 Pat 15-May A2 Brody 21-Jun
4 A1 Duff 03-May A2 Duff 09-May A3 Cash 10-May
 
Il faut d'abord créer un fonction VBA dans un module
 

Code :
  1. Public Function SimpleCSV(strSQL As String, _
  2.             Optional strDelim As String = "," ) As String
  3. 'Downloaded from theDBguy's site
  4. 'Returns a comma delimited string of all the records in the SELECT SQL statement
  5. 'Source: http://accessmvp.com/thedbguy
  6. Option Compare Database
  7. Option Explicit
  8. Public Function SimpleCSV(strSQL As String, _
  9.             Optional strDelim As String = "," ) As String
  10. 'Downloaded from theDBguy's site
  11. 'Returns a comma delimited string of all the records in the SELECT SQL statement
  12. 'Source: http://accessmvp.com/thedbguy
  13. 'v1.0 - 8/20/2013
  14. Dim db As DAO.Database
  15. Dim rs As DAO.Recordset
  16. Dim strCSV As String
  17. Set db = CurrentDb()
  18. Set rs = db.OpenRecordset(strSQL, dbOpenSnapshot)
  19. 'Concatenate the first (and should be the only one) field from the SQL statement
  20. With rs
  21.     Do While Not .EOF
  22.         strCSV = strCSV & strDelim & .Fields(0)
  23.         .MoveNext
  24.     Loop
  25.     .Close
  26. End With
  27. 'Remove the leading delimiter and return the result
  28. SimpleCSV = Mid$(strCSV, Len(strDelim) + 1)
  29. Set rs = Nothing
  30. Set db = Nothing
  31. End Function


 
Puis la requête

Code :
  1. SELECT DISTINCT tblMyData.Order, SimpleCSV("SELECT [Stage] & ' ' & [Person] & ' ' & [StageDate] FROM tblMyData WHERE [Stage] is not null And [Order] = " & [Order]," " ) AS StagePersonDateSeries
  2. FROM tblMyData;

Reply

Sujets relatifs:

Leave a Replay

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