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

MS SQL Server Discussion :

concatenation avec Stuff et group by


Sujet :

MS SQL Server

  1. #1
    Membre du Club
    Inscrit en
    Juillet 2005
    Messages
    111
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 111
    Points : 50
    Points
    50
    Par défaut concatenation avec Stuff et group by
    Bonjour à tous,

    J'aimerais utiliser la fonction Stuff qui permet de concaténer un champ par rapport à un regroupement group by.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    	Select distinct S.Num_Sys, 
    			/* stuff permet de concatener les dates pour chaque Num_Sys */
    			STUFF((SELECT '#' + CAST([VAL] AS VARCHAR(MAX))
    				FROM ELTS E1
    				WHERE (Num_sys = S.Num_sys 
    					and (ELEMENT='DT') 
    					and VAL = '20/09/2011')      
    				order by Attr
    				FOR XML PATH(''),TYPE).value('.','VARCHAR(MAX)'),1,1,'') as Date1,
    			/* stuff permet de concatener les codes CodeE pour chaque Num_Sys */
    			STUFF((SELECT '#' + CAST([VAL] AS VARCHAR(MAX))
    				FROM ELTS ES2
    				WHERE (Num_sys = S.Num_Sys 
    					and ELEMENT='Code' 
    					/* mettre aussi un critere sur le champ 'DT' puisque ce critère est non null   */
    					and exists (SELECT [ELEMENT] FROM ELTS WHERE (Num_sys = S.Num_sys and ELEMENT='DT_ACH' 
    					and VAL = '20/09/2011')))      
    				order by Nu_Attr
    				FOR XML PATH(''),TYPE).value('.','VARCHAR(MAX)'),1,1,'') as Cd_E
    From SOUS S 
    	group by S.Num_Sys;
    Je voudrais pouvoir injecter un critère dans le stuff mais je ne dois pas l'injecter dans le group by global car je voudrais garder le group by tel qu'il est.

    En fait je voudrais pouvoir synchroniser les 2 stuff (qui portent sur 2 champs différents) : dans le premier stuff sélectionner seulement la ligne qui correspond à la date '20/09/2011'
    et dans le second stuff selectionner seulement la ligne qui est associée à la date 20/09/2011' par le champ "Code1".

    voici les scripts de création des tables :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    CREATE TABLE SOUS ([NUM_SYS] INT)
    INSERT INTO SOUS ([NUM_SYS] VALUES (1);
     
    CREATE TABLE ELTS ([NUM_SYS] INT, [ELEMENT] [varchar](8), [CODE1] INT, [VAL] [varchar](20))
     
     
    INSERT INTO ELTS ([NUM_SYS], [ELEMENT], [CODE1], [VAL]) VALUES (1,'DT', 1, '20/09/2011')
     
    INSERT INTO ELTS ([NUM_SYS], [ELEMENT], [CODE1], [VAL]) VALUES (1,'Code', 1, '999')
     
    INSERT INTO ELTS ([NUM_SYS], [ELEMENT], [CODE1], [VAL]) VALUES (1,'DT', 2, '22/09/2011')
    INSERT INTO ELTS ([NUM_SYS], [ELEMENT], [CODE1], [VAL]) VALUES (1,'Code', 2, '888')
    Voici le résultat que je voudrais avoir :

    Num_Sys | Date1 | Cd_E
    1 | 20/09/2011| 999


    et non :

    Num_Sys | Date1 | Cd_E
    1 | 20/09/2011 | 999#888


    Je veux aussi garder les Stuff car j'ai d'autres enregistrements pour lesquels c'est nécessaire.

    Avez-vous des idées ?

    Merci beaucoup par avance.

    Laurent.

  2. #2
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    Si vous êtes obligé d'écrire une requête aussi complexe, c'est parce que votre modèle de données répond à ce que vous voulez, mais pas à ce dont vous avez besoin.

    Revoyez votre modèle :

    - l'écriture des requêtes en sera bien plus simple
    - les performances bien plus élevées
    - la qualité et l'intégrité des données correcte

    Ici vous auriez du avoir une colonne date et une colonne code, au lieu de tout stocker à la sauce Entite-Attribut-Valeur (EAV dans la littérature).

    Pour avoir vu ce type d’implémentation chez un éditeur de logiciels très connu auquel tout le monde croyait (ou vendait intellectuellement par le mensonge) sauf très peu de gens dont je faisais partie, il s'avère que l'application en question a été tellement contre-performante qu'elle n'a jamais vu le jour en dehors de murs de cet éditeur : avec plus de 5 utilisateurs, c'était littéralement inutilisable.

    @++

  3. #3
    Membre du Club
    Inscrit en
    Juillet 2005
    Messages
    111
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 111
    Points : 50
    Points
    50
    Par défaut
    Merci pour votre reponse.

    En effet ce serait plus facile en reconstruisant le modèle de donnees.

    Malheureusement, je ne peux pas le modifier, je dois faire avec l'existant.

    Auriez vous une idee pour mon problème ?

    Laurent.

  4. #4
    Membre éprouvé

    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 448
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 448
    Points : 1 234
    Points
    1 234
    Par défaut
    J'ai l'impression que vous vous trompez sur la nature de STUFF (qui n'a rien d'une fonction d’agrégation).
    Pour avoir une réponse vous devriez être plus précis, quels sont ces fameux critères supplémentaire que vous souhaitez injecter ?


    Par ailleurs, ce que vous cherchez est peut-être l'opérateur CROSS APPLY.
    Je vous invite à vous documentez sur son fonctionnement.

    SELECT
    - DISTINCT Num_Sys
    - CROSS APPLY 1
    - CROSS APPLY 2
    - CROSS APPLY 3
    Most Valued Pas mvp

  5. #5
    Membre du Club
    Inscrit en
    Juillet 2005
    Messages
    111
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 111
    Points : 50
    Points
    50
    Par défaut
    Merci beaucoup Sergejack pour votre réponse,

    Ce que je voulais dire par :
    Je voudrais pouvoir injecter un critère dans le stuff mais je ne dois pas l'injecter dans le group by global car je voudrais garder le group by tel qu'il est.
    c'est que je voudrais que les requêtes incluses dans les stuff comportent des critères qui permettent de les synchroniser l'une par rapport à l'autre.

    C'est à dire que si je met un critère sur la date dans le premier stuff, je voudrais que le second stuff sélectionne seulement les enregistrements qui correspondent à ceux sélectionnés dans le premier.

    Auriez-vous une solution avec les stuff pour ma problématique ?

    Je vais me pencher sur la solution avec les Cross Apply.

    Laurent

  6. #6
    Membre éprouvé

    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 448
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 448
    Points : 1 234
    Points
    1 234
    Par défaut
    Avoir plusieurs résultats de concaténation par FOR XML sur base d'un même resultset source est impossible.
    Vous pourriez faire la concaténation dans une CTE récursive mais je ne crois pas que cela soit plus performant.
    Most Valued Pas mvp

  7. #7
    Membre du Club
    Inscrit en
    Juillet 2005
    Messages
    111
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 111
    Points : 50
    Points
    50
    Par défaut
    Que signifie une "CTE récursive" ?

    Est-ce une procédure stockée ?

    Laurent.

Discussions similaires

  1. [Cognos 6][Impromptu] Problème avec les champs groupés
    Par nicoduhavre dans le forum Cognos
    Réponses: 4
    Dernier message: 23/03/2007, 15h27
  2. Requête SQL - Pb avec la clause GROUP BY
    Par jeromesco dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 10/07/2006, 09h04
  3. [C#][1.1]Concatenation avec un point
    Par Laeticia dans le forum Windows Forms
    Réponses: 2
    Dernier message: 31/05/2006, 15h36
  4. Réponses: 20
    Dernier message: 29/03/2006, 11h37
  5. [XML][XSLT] Débutant {Probléme avec For-each-group}
    Par Silvia12 dans le forum XSL/XSLT/XPATH
    Réponses: 6
    Dernier message: 29/01/2006, 21h38

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