IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement SQL Server Discussion :

Boucle pour concaténer un champ [2008R2]


Sujet :

Développement SQL Server

  1. #1
    Membre du Club
    Femme Profil pro
    Chargée de missions
    Inscrit en
    Janvier 2016
    Messages
    73
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 32
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chargée de missions

    Informations forums :
    Inscription : Janvier 2016
    Messages : 73
    Points : 58
    Points
    58
    Par défaut Boucle pour concaténer un champ
    Bonjour,

    J'ai une table temporaire, qui se présente comme ceci :
    RANG ID_1 ID_2 STATUT
    1 002 005 Manque date de naissance
    2 002 005 Code postal invalide
    1 003 004 Adresse mail invalide
    2 003 004 Code postal invalide
    3 003 004 Portable invalide
    1 006 008 Code postal invalide


    J'aimerau pouvoir concaténer les différents statuts pour les couples "ID_I"/"ID_2" comme suit :
    ID_1 ID_2 STATUT
    002 005 Manque date de naissance | Code postal invalide
    003 004 Adresse mail invalide | Code postal invalide | Portable invalide
    006 008 Code postal invalide

    J'ai créé un rang dans ma table temporaire, pensant que ça pourrait aider par la suite, mais je ne sais pas comment m'y prendre... Si vous pouviez m'aiguiller ! Merci beaucoup

  2. #2
    Invité
    Invité(e)
    Par défaut
    Y a sûrement mieux mais essaie un truc comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    DECLARE @tab TABLE (id INT, val CHAR(1)) ; INSERT @tab (id, val) VALUES ( 1, 'a') , ( 1, 'b') , ( 1, '2' ) , ( 2, 'x' ) , ( 2, 'Z' )
    ; with SR as ( SELECT id, val FROM @tab )
    SELECT DISTINCT SR3.id , SUBSTRING(SR2.ligne, 5, LEN(SR2.ligne)-9) AS ligne
    FROM SR AS SR3
    CROSS APPLY ( select replace(cast((select val as[*] from SR WHERE SR3.id = SR.id ORDER by val FOR XML PATH('tr'), TYPE) as varchar (max)), '</tr><tr>', ', ' ) ligne ) AS SR2

  3. #3
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    733
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2003
    Messages : 733
    Points : 1 668
    Points
    1 668
    Billets dans le blog
    8
    Par défaut
    Ou bien quelque chose présentée différemment comme ceci :

    . Solution 1
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT
         T.ID_1, T.ID_2, 
         STUFF( (SELECT ' | ' + Z.STATUT  FROM #TmpStatut Z  WHERE Z.ID_1 = T.ID_1  AND Z.ID_2 = T.ID_2 FOR XML PATH ('')), 1, 3, '')  AS ConcatStatuts 
    FROM #TmpStatut AS T
    GROUP BY T.ID_1, T.ID_2
    ORDER BY T.ID_1, T.ID_2
    . Solution 2
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ; WITH T AS  ( SELECT ID_1, ID_2 , STATUT 
    			   FROM #TmpStatut 
    			  )     
    SELECT DISTINCT   T.ID_1, T.ID_2, SR2.ConcatStatuts 
    FROM T 
    CROSS APPLY ( SELECT STUFF( (SELECT ' | ' + Z.STATUT  
    			 FROM T  AS Z 
    			 WHERE Z.ID_1 = T.ID_1  
    			 AND   Z.ID_2 = T.ID_2 FOR XML PATH ('')), 1, 3, '') ConcatStatuts ) AS SR2
    . Solution 3
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    ; WITH T AS  ( SELECT ID_1, ID_2, STATUT 
    			   FROM #TmpStatut 
    			  )  
    , R AS  ( SELECT ID_1, ID_2 
    		  FROM #TmpStatut
    		  GROUP BY ID_1, ID_2    
    		 )  		     
    SELECT R.ID_1, R.ID_2, SR2.ConcatStatuts 
    FROM R 
    CROSS APPLY ( SELECT STUFF( (SELECT ' | ' + Z.STATUT  
    			 FROM T  AS Z 
    			 WHERE Z.ID_1 = R.ID_1  
    			 AND   Z.ID_2 = R.ID_2 FOR XML PATH ('')), 1, 3, '') ConcatStatuts ) AS SR2
    ORDER BY R.ID_1, R.ID_2
    Remarque :
    - Les 3 solutions donnent le même résultat ci-dessous :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ID_1	ID_2	ConcatStatuts
    002		005		Manque date de naissance | Code postal invalide
    003		004		Adresse mail invalide | Code postal invalide | Portable invalide
    006		008		Code postal invalide

    - La solution 2 est pratiquement la même que celle proposée par 7gyY9w1ZY6ySRgPeaefZ
    - Les plans d'exécution de la "solution 1" et de la "solution 3" sont exactement identiques
    - Le plan d'exécution de la "solution 2" est un peu différent des plans d'exécution des solution 1 ou 2
    - Les performances (I/O, CPU, .. ) des 3 solutions sont pratiquement identiques

    A+

  4. #4
    Membre actif
    Inscrit en
    Juin 2006
    Messages
    229
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 229
    Points : 266
    Points
    266
    Par défaut
    À partir de SQL Server 2017, il existe la fonction qui tue : STRING_AGG
    https://docs.microsoft.com/en-us/sql...g-transact-sql

    @+

  5. #5
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 897
    Points : 53 133
    Points
    53 133
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par Zabriskir Voir le message
    À partir de SQL Server 2017, il existe la fonction qui tue : STRING_AGG
    https://docs.microsoft.com/en-us/sql...g-transact-sql
    @+
    Et de surcroit, BEAUCOUP, BEAUCOUP plus rapide que les deux autres solutions !!!!!!

    A +

  6. #6
    Membre du Club
    Femme Profil pro
    Chargée de missions
    Inscrit en
    Janvier 2016
    Messages
    73
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 32
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chargée de missions

    Informations forums :
    Inscription : Janvier 2016
    Messages : 73
    Points : 58
    Points
    58
    Par défaut
    Bonjour à tous !
    Et merci pour vos nombreux retours.

    J'ai utilisé la fonction 1, proposée par Hmira... Une merveille !

    Effectivement, en parcourant Internet, j'avais vu la fonction STRING_AGG mais je ne suis pas en version 2017.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2010] Envoi mail par excel avec boucle pour tous les champs
    Par jul2012 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 12/11/2012, 14h54
  2. Problème pour concaténer mes champs
    Par jacko842 dans le forum SQL
    Réponses: 7
    Dernier message: 03/11/2011, 15h24
  3. Boucle pour concaténer datasets
    Par debdev dans le forum Macro
    Réponses: 6
    Dernier message: 22/06/2009, 14h15
  4. [MySQL] boucle pour chaque entrée dans un champ
    Par boubourse92 dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 28/11/2008, 01h52
  5. Requête SQL pour concaténer un même champs
    Par aureliegro dans le forum IHM
    Réponses: 14
    Dernier message: 18/12/2007, 15h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo