Concat ou autre chose ? - SQL/NoSQL - Programmation
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.
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
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.
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.
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 :
|
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)...
Marsh Posté le 27-04-2010 à 11:07:28
c'est mon algo ca 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
Marsh Posté le 27-04-2010 à 11:10:36
C'est ton algo mais tu l'avais pas posté
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.
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 :
|
voila le bout de code pour ca
apres j'pensais a rouvrir mon fichier exel
Code :
|
et à faire mon traitement mais traiter un fichier excel j'ai beau chercher j'ai pas (encore) trouvé chaussure a mon pied
Marsh Posté le 27-04-2010 à 11:20:17
faire un dataset au lieu d'utiliser excel direct ? c'est mieux ?
Marsh Posté le 27-04-2010 à 11:28:57
Bin certainement
Après tu dois bien pouvoir transformer un tableau en fichier excel non ?
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
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
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****
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.
Marsh Posté le 27-04-2010 à 11:45:18
j'need un excel a cause de ce bout de code la
Code :
|
ca me sert pour outlook donc excel obligatoire
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 :
|
Et là attention le mal de crane :
Code :
|
(et les deux = ne sont pas une erreur de syntaxe)
Marsh Posté le 27-04-2010 à 12:03:29
OMG j'y comprends rien
hum c'est avant mon select que j'fais ca ? ou c'est un procédure stockée pure et simple la
Marsh Posté le 27-04-2010 à 12:07:31
j'vais mettre la requete que j'fais la attention ca pique
Code :
|
le resultat de cette requete est bien sur un produit cartesien de ce que je veux car les contacts ont plusieurs roles
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 :
|
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
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
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 :
|
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
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.
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 !
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.
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 :
|
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 ?
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