Concat ou autre chose ?

Concat ou autre chose ? - SQL/NoSQL - Programmation

Marsh Posté le 27-04-2010 à 10:29:45    

Bonjour,
 
Voilà mon pb j'ai une requete SQL qui me genere tous les attributs des contacts de ma société (nom, tel, adresse, etc)
 il y a un attribut en plus que l'on apelle "role" mais le truc c'est que des personnes peuvent avoir plusieurs roles.
 
J'vous montre le resultat de la premiere requete
 
Prénom       Nom        Num    ID
Toto          tata       666     22
 
et la requete qui me donne les roles
 
ID      Valeur
22       titi
22       tutu
 
 
 
le but est d'arriver apres traitement a ca  
 
Prénom      Nom       Num    ID      Role
Toto          tata       666     22   titi, tutu
 
 
une idée ?  
 
 
NB : je bosse sous SQL server 2005  donc pas de fonction CONCAT() si pratique en MySQL
 
j'ai une preference de traitement en VB.NET (mon prog tourne avec ce langage)
 
NB2 : mon appli fait
           -connexion a la DB
           -requete SQL
           -on colle le resultat dans excel
           -divers traitement avec outlook  
 
voilà


Message édité par hazzelthorn le 27-04-2010 à 10:32:45
Reply

Marsh Posté le 27-04-2010 à 10:29:45   

Reply

Marsh Posté le 27-04-2010 à 10:39:29    

Salut,

 

Sans passer par une proc stockée, je ne vois pas comment concaténer N champs vu la manière dont tu présentes les choses.

 

Si tu ne veux utiliser qu'une seule requête, il te faudra passer par un post-traitement dans la partie VB.

 

Pour info, concat() en MYSQL a un équivalent dans toutes les autres bases de données (sous SQL Server, ça doit être l'opérateur +) : mais elle ne te servira pas ici, en tout cas pas vu la manière dont tu présentes les choses.


Message édité par Fred999 le 27-04-2010 à 10:39:50
Reply

Marsh Posté le 27-04-2010 à 10:43:48    

Pour rappel, un SGBD n'est pas sensé faire de la présentation (mise en forme). C'est à l'appli au-dessus de le faire ;)


---------------
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 27-04-2010 à 10:47:04    

du PL/SQL ? par ex ? edit : oracle sa :/
 
pour le post traitement en VB j'vois pas comment faire :/ si vous avez des pistes je prends
 
 
et je sais très bien qu'un SGBD ne fait pas de la presentation néanmoins sur un exemple simple l'utilisation de jointure reflexive peut m'aider mais pas ici.


Message édité par hazzelthorn le 27-04-2010 à 10:50:06
Reply

Marsh Posté le 27-04-2010 à 10:54:57    

SQL Server ne permet pas de procs stocks ? oO
 
Pour le post-traitement (moche mébon), il faut une requête qui te renvoie un truc comme :
 
Prénom       Nom        Num    ID  Role
Toto          tata       666     22   toto
Toto          tata       666     22   tutu
 
Tu browses le tableau, et tu concatènes au fur et à mesure les Role sur le même ID.

Reply

Marsh Posté le 27-04-2010 à 10:56:24    

j'ai deja ce que tu montre mais le traitement a faire   j'vois pas comment le faire
 
Edit : en vb j'parle, j'me bat pour parser mon fichier Excel sans succes, le mieux serait de faire ce traitement avant la sauvegarde de mon fichier excel
 
j'ai testé des truc du style  
 

Code :
  1. nb = Range("B" & i & "" ).Value
  2. Sheets("nb rebut" ).Select
  3.   Range("C" & j & "" ).Value = nb


 


Message édité par hazzelthorn le 27-04-2010 à 11:03:54
Reply

Marsh Posté le 27-04-2010 à 11:05:54    

On va le faire en pseudo-code
 
Suppose que le résultat SQL soit dans un tableau mon_tableau
 
tu déclares trois variables :
- une pour contenir l'identifiant de chaque personne, id
- un compteur
- un pour le rôle
 
tu initialises id à une valeur fantaisiste et ton compteur à 0
 
puis une boucle :  
 
pour chaque ligne de mon_tableau {
 
  si id est différent de l'id de la ligne courante du tableau {
    id = id de la ligne courante du tableau
    rôle = rôle de la ligne courante du tableau
  }
  sinon {
    rôle = rôle + ', ' + rôle de la ligne courante du tableau
  }
 
}
 
Ca c'est une base qui te permet de concaténer tous les rôles pour un même id, il te faut faire d'autres trucs dans le code, comme mémoriser les noms et prénoms courants (comme l'id)...

Reply

Marsh Posté le 27-04-2010 à 11:07:28    

c'est mon algo ca :d mais la conversion  en VB :@
 
merci de m'aider !
 
faut que j'demande a des pro VB la :/
 
j'avais fait ds l'ordre
 
1) creation d'un dataset + "collage" de mon select dans celui ci
2)je parse mon resultat comme tu l'as mentionné ds le pseudo -code
3) EPIC fail du resultat :)


Message édité par hazzelthorn le 27-04-2010 à 11:09:47
Reply

Marsh Posté le 27-04-2010 à 11:10:36    

C'est ton algo mais tu l'avais pas posté :o

 

Franchement c'est pas trop compliqué à coder en VB, avec l'aide tu peux te débrouiller, il faut savoir déclarer un tableau (ce qui peut être vite lourd mébon je ne connais pas les dernières versions) et utiliser une boucle, le reste... en gros t'ouvres 3 pages de l'aide : déclaration de variables, déclaration de tableaux, structures conditionnelles.


Message édité par Fred999 le 27-04-2010 à 11:10:43
Reply

Marsh Posté le 27-04-2010 à 11:12:06    

j'ai beau taper F1 comme un porc ds VS2005 j'ai rien :d

Reply

Marsh Posté le 27-04-2010 à 11:12:06   

Reply

Marsh Posté le 27-04-2010 à 11:13:58    

tu sais, il y a l'aide MSDN en ligne [:kapukapu]

Reply

Marsh Posté le 27-04-2010 à 11:15:57    

je cherche je cherche mais declarer un tableau me sert a rien dans mon cas comme la requete SQL me génére un boo fichier excel
 

Code :
  1. ' =============================== On génére un fichier excel a partirs d'une requête ==========================
  2.             Try
  3.                 With xsTransfert.QueryTables.Add(Connection:="ODBC;DRIVER=SQL Server;SERVER=NEPTUNE;APP=Microsoft® Query;DATABASE=absyss;Integrated Security=True", Destination:=xsTransfert.Range("A1" ))
  4.                     .CommandText = System.Configuration.ConfigurationSettings.AppSettings(str) ' ou requete SELECT"
  5.                     .Name = "feuil1"
  6.                     .FieldNames = True
  7.                     .RowNumbers = True
  8.                     .FillAdjacentFormulas = False
  9.                     .PreserveFormatting = True
  10.                     .RefreshOnFileOpen = False
  11.                     .BackgroundQuery = True
  12.                     .RefreshStyle = Excel.XlCellInsertionMode.xlOverwriteCells
  13.                     .SavePassword = False
  14.                     .SaveData = True
  15.                     .AdjustColumnWidth = True
  16.                     .RefreshPeriod = 0
  17.                     .PreserveColumnInfo = True
  18.                     .Refresh(BackgroundQuery:=False)
  19.                 End With
  20.             Catch bug As Exception
  21.                 MsgBox("Va bosser ca marche pas" )
  22.             End Try
  23.             'Sauvegarde de mon export SQL dans un fichier excel
  24.             xsTransfert.SaveAs("C:\" + d.ToString + " " + d2.ToString + " " + dossier + ".xls" )


 
voila le bout de code pour ca
 
 
apres j'pensais a rouvrir mon fichier exel
 

Code :
  1. xlApp.Workbooks.Open("C:\" + d.ToString + " " + d2.ToString + " " + dossier + ".xls" )


 
et à faire mon traitement  mais traiter un fichier excel j'ai beau chercher j'ai pas (encore) trouvé chaussure a mon pied :)


Message édité par hazzelthorn le 27-04-2010 à 11:18:04
Reply

Marsh Posté le 27-04-2010 à 11:20:17    

faire un dataset au lieu d'utiliser excel direct ? c'est mieux ?

Reply

Marsh Posté le 27-04-2010 à 11:28:57    

Bin certainement :D
 
Après tu dois bien pouvoir transformer un tableau en fichier excel non ?

Reply

Marsh Posté le 27-04-2010 à 11:30:55    

nop ca genere du XML :/  
 
parcourir un fichier excel et applique mon if elif end if  j'vois pas du tout mm le MSDN ne m'aide pas

Reply

Marsh Posté le 27-04-2010 à 11:33:31    

j'vais poster en section VB j'pense la :d

Reply

Marsh Posté le 27-04-2010 à 11:36:22    

Mais... tu pars bien d'une base de données non ?
 
Donc : Base de données => récupération VB => traitement VB => fichier Excel

Reply

Marsh Posté le 27-04-2010 à 11:41:25    

connexion BDD avec VB => requete SQL => recup resultat avec VB => stock ds fichier excel j'peux pas jouer dessus car c'est une fonction de VS 2005 que j'use (avec le framework 3.5.1)
 
donc resultat j'dois faire un post traitement avec mon fichier excel de m****  :fou:


Message édité par hazzelthorn le 27-04-2010 à 11:42:51
Reply

Marsh Posté le 27-04-2010 à 11:44:05    

si y'a pas besoin de mise en forme du résultat, un csv peut suffire pour excel.


---------------
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 27-04-2010 à 11:45:18    

j'need un excel a cause de ce bout de code la  
 
 

Code :
  1. '===============================================Importatation  fichier généré dans outlook ====================
  2.             If System.Configuration.ConfigurationSettings.AppSettings("outlook" ) = 1 Then
  3.                 Dim ex As Object
  4.                 Dim oCont As Outlook.ContactItem
  5.                 Dim lig As Short
  6.                 'ici on va créer le dossier contact s'il n'existe pas
  7.                 Dim NS As Outlook.NameSpace
  8.                 Dim colCTSItems As Object
  9.                 NS = OutlookApplication_definst.Application.GetNamespace("MAPI" )
  10.                 'On teste si le dossier de destination  existe déjà
  11.                 Try
  12.                     NS.GetDefaultFolder(Outlook.OlDefaultFolders.olPublicFoldersAllPublicFolders).Folders(dossier).Delete()
  13.                 Catch exx As Exception
  14.                 End Try
  15.                 'On crée le dossier de destination en se placant dans DossierPublic/Tous les dossiers publics
  16.                 colCTSItems = NS.GetDefaultFolder(Outlook.OlDefaultFolders.olPublicFoldersAllPublicFolders).Folders.Add(dossier, Outlook.OlDefaultFolders.olFolderContacts)
  17.                 ' Définie le dossier comme carnet d'adresse
  18.                 colCTSItems.ShowAsOutlookAB = True
  19.                 Err.Clear()
  20.                 ex = xlApp.Workbooks.Open("C:\" + d.ToString + " " + d2.ToString + " " + dossier + ".xls" )
  21.                 lig = 2
  22.                 Do Until ex.Sheets("Feuil1" ).Cells(lig, 2).Value = ""
  23.                     'ici on créé un nouveau contact
  24.                     oCont = colCTSItems.Items.Add(Outlook.OlItemType.olContactItem)
  25.                     'Nom
  26.                     oCont.FirstName = ex.Sheets("Feuil1" ).Cells(lig, 3).Value
  27.                     'Prénom
  28.                     oCont.LastName = ex.Sheets("Feuil1" ).Cells(lig, 4).Value
  29.                     'Adresse du Bureau
  30.                     oCont.BusinessAddressStreet = ex.Sheets("Feuil1" ).Cells(lig, 6).Value + Chr(13) + ex.Sheets("Feuil1" ).Cells(lig, 17).Value
  31.                     'Nom Complet / Titre
  32.                     oCont.Title = ex.Sheets("Feuil1" ).Cells(lig, 2).Value
  33.                     'Titre
  34.                     oCont.JobTitle = ex.Sheets("Feuil1" ).Cells(lig, 13).Value
  35.                     'Adresse Bureau/ Ville
  36.                     oCont.BusinessAddressCity = ex.Sheets("Feuil1" ).Cells(lig, 9).Value
  37.                     'Adresse Bureau/ Code postal
  38.                     oCont.BusinessAddressPostalCode = ex.Sheets("Feuil1" ).Cells(lig, 8).Value
  39.                     'Société
  40.                     oCont.CompanyName = ex.Sheets("Feuil1" ).Cells(lig, 5).Value
  41.                     'Ville Bureau
  42.                     'oCont.BusinessAddressCountry = ex.Sheets("Feuil1" ).Cells(lig, 15).Value
  43.                     'Classer Sous / Nom du manager
  44.                     oCont.ManagerName = ex.Sheets("Feuil1" ).Cells(lig, 14).Value
  45.                     'Numero de telephone Bureau
  46.                     oCont.BusinessTelephoneNumber = ex.Sheets("Feuil1" ).Cells(lig, 10).Value
  47.                     'Numero de telephone 2  pro
  48.                     'oCont.Business2TelephoneNumber = ex.Sheets("Feuil1" ).Cells(lig, 33).Value
  49.                     'Numero de telephone domicile
  50.                     'oCont.HomeTelephoneNumber = ex.Sheets("Feuil1" ).Cells(lig, 38).Value
  51.                     'Autre Numero de telephone
  52.                     'oCont.OtherTelephoneNumber = ex.Sheets("Feuil1" ).Cells(lig, 40).Value
  53.                     'Numero de telephone / télécopie (bureau)
  54.                     oCont.BusinessFaxNumber = ex.Sheets("Feuil1" ).Cells(lig, 11).Value
  55.                     'Numero de telephone / telephone mobile
  56.                     oCont.MobileTelephoneNumber = ex.Sheets("Feuil1" ).Cells(lig, 15).Value
  57.                     'Numero de telephone / Domicile
  58.                     oCont.HomeTelephoneNumber = ex.Sheets("Feuil1" ).Cells(lig, 16).Value
  59.                     'Adresse de messagerie
  60.                     oCont.Email1Address = ex.Sheets("Feuil1" ).Cells(lig, 12).Value
  61.                     'Role
  62.                     'oCont.Journal = ex.Sheets("Feuil1" ).Cells(lig, 12).Value
  63.                     lig = lig + 1
  64.                     oCont.Save()
  65.                 Loop
  66.             End If


 
ca me sert pour outlook   donc excel obligatoire

Reply

Marsh Posté le 27-04-2010 à 11:57:55    

C'est possible en SQLServer mais il faut imbriquer de la requête :  
 
On commence par déclarer deux variables et les initialiser :  

Code :
  1. declare
  2.     @list varchar(8000),
  3.     @lasti int
  4. select
  5.     @list = '',
  6.     @lasti = -1


 
 
Et là attention le mal de crane :  
 

Code :
  1. update laTable
  2. set
  3.     @list = Concatentation = case when @lasti <> ID
  4.                                   then Valeur
  5.                                   else @list + Valeur
  6.                              end,
  7.     @lasti = ID


 
(et les deux = ne sont pas une erreur de syntaxe)


Message édité par tinfolley le 27-04-2010 à 11:58:21
Reply

Marsh Posté le 27-04-2010 à 12:03:29    

OMG j'y comprends rien :d  
 
hum c'est avant mon select que j'fais ca ? ou c'est un procédure stockée pure et simple la  

Reply

Marsh Posté le 27-04-2010 à 12:07:31    

j'vais mettre la requete que j'fais la attention ca pique  
 
 

Code :
  1. SELECT distinct r_civ.CivDsc as Titre,
  2. p_ctc.CtcFstNamDsc as Prénom,
  3. p_ctc.CtcNamDsc as Nom,
  4. p_cpy.CpyTrdNamDsc as Société,
  5. p_cpyaddr.CpyAddrStreet1Dsc as RueBureau,
  6. p_cpyaddr.CpyAddrStreet2Dsc as Ruebureau2,
  7. p_cpyaddr.CpyAddrZipDsc as Codepostal,
  8. p_cpyaddr.CpyAddrExCde as Villebureau,
  9. p_ctc.CtcPhnNum,
  10. p_ctc.CtcFaxNum,
  11. p_ctc.CtcMailNum,
  12. p_ctc.DtyDsc as Titre1, 
  13. p2.ctcNamDsc as Nomabs,
  14. p2.ctcFstNamDsc as PrenomAbs,
  15. p2.RcdCreateHrd as Creation_contact,
  16. p2.RcdMdfHrd as Modification_contact,
  17. p_ctcchar.charval                                  'CECI represente les role'
  18. FROM p_cpy, p_cpyaddr, p_ctc, r_civ, r_deal, p_cpydeal, p_cpycust ,p_ctcchar,p_ctc as p2
  19. WHERE p_cpycust.CpyInCde = p_cpy.CpyInCde
  20. AND r_deal.DealInCde = p_cpydeal.DealInCde
  21. and p_ctcchar.CtcInCde = p_ctc.ctcincde                 'LIEN TABLE "role" avec le reste'
  22. and p_cpydeal.CpyInCde = p_cpy.CpyInCde
  23. AND  r_civ.CivInCde = p_ctc.CivInCde
  24. and p_ctc.OperCtcInCde = p2.CtcIncde
  25. AND p_cpy.CpyInCde = p_cpyaddr.CpyInCde
  26. And p_cpyaddr.CpyAddrInCde = p_ctc.CpyAddrInCde
  27. AND p_ctc.ctcInCde >0
  28. AND p_ctc.ctcNamDsc != 'KIMWEB'
  29. AND p_ctc.CtcFstNamDsc != 'KIMWEB'
  30. AND p_ctc.ctcNamDsc != 'VITO'
  31. AND p_ctc.ValidPnt != 0
  32. AND p_cpy.cpyStsInCde = 2
  33. AND p_cpy.ValidPnt != 0
  34. AND p_cpy.CpyInCde != 1000
  35. and (p_cpydeal.DealInCde = 104 OR p_cpydeal.DealInCde = 105)
  36. AND p_cpycust.CtcInCde != 10002719
  37. AND p_cpycust.CtcInCde != 10000001


 
le resultat de cette requete est bien sur un produit cartesien de ce que je veux  car les contacts ont plusieurs roles :)


Message édité par hazzelthorn le 27-04-2010 à 12:08:45
Reply

Marsh Posté le 27-04-2010 à 12:55:31    

En fait il faudrait passer par une table temporaire.
Peux-tu me mettre un script de création de tes tables avec quelqueq exemples de données
 
Si je te fais avec un exemple que j'ai en stock :  
En gros je veut obtenir :  
 
IdUtilisateur Email Concatenation  
1 | toto@titi.com |Commentaire 1, Commentaire 2, Commentaire 3
9 | tata@titi.com |Commentaire 1, Commentaire 2, Commentaire 3
 
A partir d'un jeu de données :
 
IdLigne IdUtilisateur Email Texte Concatentation
1 1 toto@titi.com Commentaire 1 NULL
2 1 toto@titi.com Commentaire 2 NULL
3 1 toto@titi.com Commentaire 3 NULL
4 9 tata@titi.com Commentaire 1 NULL
5 9 tata@titi.com Commentaire 2 NULL
6 9 tata@titi.com Commentaire 3 NULL
 
 

Code :
  1. --Création d'une table avec les données
  2. CREATE TABLE #TMP (IdLigne INT IDENTITY,
  3.                    IdUtilisateur INT,
  4.                    Email VARCHAR(512),
  5.                    Texte VARCHAR(512),
  6.                    Concatentation VARCHAR(4000))
  7. --remplissage
  8. INSERT INTO #TMP (IdUtilisateur,Email,Texte) VALUES (1,'toto@titi.com','Commentaire 1')
  9. INSERT INTO #TMP (IdUtilisateur,Email,Texte) VALUES (1,'toto@titi.com','Commentaire 2')
  10. INSERT INTO #TMP (IdUtilisateur,Email,Texte) VALUES (1,'toto@titi.com','Commentaire 3')
  11. INSERT INTO #TMP (IdUtilisateur,Email,Texte) VALUES (9,'tata@titi.com','Commentaire 1')
  12. INSERT INTO #TMP (IdUtilisateur,Email,Texte) VALUES (9,'tata@titi.com','Commentaire 2')
  13. INSERT INTO #TMP (IdUtilisateur,Email,Texte) VALUES (9,'tata@titi.com','Commentaire 3')
  14. --déclaration de variables
  15. declare
  16.     @list varchar(8000),
  17.     @lasti int
  18. select
  19.     @list = '',
  20.     @lasti = -1
  21. --update de concatenation
  22. update
  23.     #TMP
  24. set
  25.     @list = Concatentation = case when @lasti <> IdUtilisateur
  26.                                   then Texte + ', '
  27.                                   else @list + Texte + ', '
  28.                              end,
  29.     @lasti = IdUtilisateur
  30. --select final ne prends la dernière ligne et enlève la virgule qui traine à la fin
  31. select  Email,
  32.     SUBSTRING(Concatentation,1,LEN(Concatentation) - 1) AS Concatentation
  33. from (SELECT Max(IdLigne) as IdLigne
  34.   FROM #TMP
  35.    GROUP BY IdUtilisateur) as a
  36. inner join #TMP as b
  37. on a.IdLigne = b.idLigne
  38. DROP TABLE #TMP


 
 
PS : je tiens à ajouter que ce script fonctionne très bien et obtiens de bon temps de réponse même sur des centaines de milliers de lignes


Message édité par tinfolley le 27-04-2010 à 13:21:40
Reply

Marsh Posté le 27-04-2010 à 13:48:35    

un script de création de mes tables ben j'en ai aucun car le resultat de mon tableau dans mon fichier excel est le resultat de ma requete SQL cité plus haut.
Et j'viens d'apprendre que procédure stockée j'oublie, le boss veut pas de custom sur la DB

Reply

Marsh Posté le 27-04-2010 à 13:57:28    

J'avais raté un élément important sur ton premier post :)
 
tu es en SQL 2005 tu peux donc utiliser les CTE (les instructions récursives).
 
Donc si je reprends mon exemple précédent :  
 
 

Code :
  1. CREATE TABLE TableTemp
  2. (IdTable   INT IDENTITY,
  3. IdUtilisateur     INTEGER NOT NULL,
  4. Email    VARCHAR(50) NOT NULL,
  5. Texte           VARCHAR(32) NOT NULL);
  6. INSERT INTO TableTemp (IdUtilisateur,Email,Texte) VALUES (1,'toto@titi.com','Commentaire 1')
  7. INSERT INTO TableTemp (IdUtilisateur,Email,Texte) VALUES (1,'toto@titi.com','Commentaire 2')
  8. INSERT INTO TableTemp (IdUtilisateur,Email,Texte) VALUES (1,'toto@titi.com','Commentaire 3')
  9. INSERT INTO TableTemp (IdUtilisateur,Email,Texte) VALUES (9,'tata@titi.com','Commentaire 1')
  10. INSERT INTO TableTemp (IdUtilisateur,Email,Texte) VALUES (9,'tata@titi.com','Commentaire 2')
  11. INSERT INTO TableTemp (IdUtilisateur,Email,Texte) VALUES (9,'tata@titi.com','Commentaire 3')
  12. GO
  13. WITH concatenationCTE (champConcat, IdUtilisateur, Email, position)
  14. AS
  15. (
  16. SELECT CAST(Texte AS VARCHAR(max)) + ', '  as champConcat,
  17.    A.IdUtilisateur,
  18.    A.Email,
  19.    B.IdTable
  20. FROM   TableTemp A
  21. INNER JOIN (SELECT MIN(IdTable) AS IdTable
  22.   FROM   TableTemp
  23.   GROUP BY IdUtilisateur) as B
  24. ON A.IdTable = B.Idtable
  25. UNION ALL
  26. SELECT champConcat + CAST(Texte AS VARCHAR(max)) + ', ' as champConcat,
  27.        concatenationCTE.IdUtilisateur,
  28.        concatenationCTE.Email,
  29.        IdTable
  30. FROM   TableTemp AS suiv
  31. INNER JOIN concatenationCTE
  32. ON suiv.IdUtilisateur = concatenationCTE.IdUtilisateur
  33. AND suiv.Email = concatenationCTE.Email
  34. AND suiv.IdTable = concatenationCTE.position + 1
  35. ),
  36. maxchampConcat
  37. AS
  38. (
  39. SELECT IdUtilisateur, MAX(position) AS maxposition
  40. FROM   concatenationCTE
  41. GROUP  BY IdUtilisateur
  42. )
  43. SELECT P.IdUtilisateur AS IdUtilisateur,
  44.    P.Email,
  45.    substring(champConcat,1,len(champConcat)-1) AS champConcat
  46. FROM   concatenationCTE AS P
  47. INNER JOIN maxchampConcat AS M
  48. ON P.IdUtilisateur = M.IdUtilisateur
  49. AND P.position = M.maxposition
  50. ORDER  BY P.IdUtilisateur
  51. GO
  52. DROP TABLE TableTemp


 
 
Alors je sais çà peut faire peur, mais c'est pas si compliqué que çà :
 - On oublie les premières lignes jusqu'au GO c'est pour initialiser les jeux de données.
 - Le résultat que l'on souhaite est tout à la fin
 - on déclare deux vues récursives avec les WITH (dans ce cas concatenationCTE & maxChampConcat)
 - La seconde permet juste de récupérer la dernière ligne de chaque élément (dans mon exemple des utilisateurs)
 - la premier fait justement le travail de concaténation avec deux étapes majeures  
    - le premier select récupère la première ligne de chaque utilisateur
    - le second select EST la requête recursive (le + dans "champConcat" et le position +1 dans ConcatenationCTE)
 
 
Franchement çà peut paraître difficile à assimiler mais ça vaut le coup de s'y attarder car c'est super puissant comme fonctionnalité tu as pas mal d'infos ici :  
http://sqlpro.developpez.com/cours [...] ecursives/
 
Après tu fais comme tu veux et comme tu peux mais bon aller retraiter des données dans Excel ou autre de façon unitaire ... je veut bien mais c'est un peu contre productif vis a vis d'un SQL pur et dur


Message édité par tinfolley le 27-04-2010 à 13:59:46
Reply

Marsh Posté le 27-04-2010 à 14:06:28    

C'est dommage qu'il n'y ai pas un equivalent a la commande CONCAT qui fonctionne en aggregation (comme COUNT ou MAX), ca resoudrai ce genre de probleme :)
 
@tinfolley: Si tu as l'occasion tu pourrais comparer les perfs de ton exemple sans CTE et avec CTE?
Il me semble que l'exemple sans CTE devrai fonctionner bcp plus vite avec beaucoup de rows.

Reply

Marsh Posté le 27-04-2010 à 14:26:41    

tinfolley on t'as dit que tu etais un dieu vivant ? par contre sur une exemple simple c'est good mais ma grosse requete la j''essaye et j'men sors pas !


Message édité par hazzelthorn le 27-04-2010 à 14:26:52
Reply

Marsh Posté le 27-04-2010 à 18:45:02    

@Oliiii tu as raison le CTE est moins performant mais il faut monter sur beaucoup de lignes
Pour info je viens de faire un test avec un million j'ai 30 secondes d'écart en gros.
Le gros avantage c'est que tu fais tout en une seule requête.
 
@hazzelthorn : essaye de faire un cas très simple pour assimiler le principe puis ensuite tu enrichi ta requête avec toutes les colonnes dont tu as besoin.


Message édité par tinfolley le 27-04-2010 à 18:45:45
Reply

Marsh Posté le 28-04-2010 à 10:56:12    

bon j'ai refais la génération du tableau excel en ecrivant ligne a ligne mes enregistrements.
 
ca donne ca  
 

Code :
  1. For y = 0 To nbcol - 1
  2.             'En tête
  3.             xlSheet.Cells(1, y + 1) = data.Tables("RECHERCHE" ).Columns(y).ColumnName
  4.             For x = 0 To NbRow - 1
  5.                 'On rempli la case
  6.                 xlSheet.Cells(x + 2, y + 1) = data.Tables("RECHERCHE" ).Rows(x).Item(y).ToString
  7.             Next
  8.             Next


 
maintenant j'dois faire mon traitement en fonction des ID role etc
 
et la j'vois pas comment l'inserer dans cette boucle  
 
une idée ?


Message édité par hazzelthorn le 28-04-2010 à 10:56:48
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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