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 :

Un pivot sans somme ou autre opération


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Avatar de zooffy
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Août 2004
    Messages
    3 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Bâtiment

    Informations forums :
    Inscription : Août 2004
    Messages : 3 895
    Par défaut Un pivot sans somme ou autre opération
    Bonjour

    Je découvre le principe du Pivot en SQL 2005. J'ai farfouillé dans les tuto et j'ai trouvé des truc super interressant, mais je n'arrive pas à reproduire les exemples pour mon cas.
    Dans ce que j'ai vu, je vois toujours une somme ou une moyenne, enfin une opération de masse. Moi, j'ai juste besoins de retourner la table (sans mauvais jeu de mot....)

    En fin de post je mets du code pour créer la table et mettre des données dedans.
    Mon contexte : je stocke des infos sur des membres d'un site dans une table sur trois colonnes :
    • l'identifiant du membre
    • l'ID du champ de fomulaire our savoir de quelle info on parle
    • la valeur de l'info elle même

    Ceci me permt de faire des formulaires dynamiques qui n'ont pas tous le même nombre de champ. ça marche super bien pour fabriquer des formulaires en ligne à la volée, enregistrer les infos et les restituer. Maintenant il faut que je puisse interroger et faire des sélections de membre.

    Donc je me suis dis que je pouvait "retourner" la table pour chaque membre trouvé. Et vu que j'ai entendu parler de PIVOT, je me suis dit que c'était la bonne solution, sauf que j'arrive pas à le mettre en place.

    Dans le code qui suit j'ai la table, avec 4 membres qui ont deux info
    • Sexe, Id_Info_Formulaire = 1
    • Statut, Id_Info_Formulaire = 2


    Et je voudrais avoir un résulat qui me présente une table qui ferait :
    UserId, Sexe, Statut

    Lorsque je mets ce code là
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT BASE.UserId, [Sexe], [Statut]
     FROM dbo.SITE_Information_Membre BASE
     
    PIVOT (
    	BASE.Valeur_Info
    	FOR BASE.Id_Info_Formulaire IN ([Sexe], [Statut])
    ) AS P
    Il me dit :
    Msg*156, Niveau*15, État*1, Ligne*9
    Syntaxe incorrecte vers le mot clé 'FOR'.
    Merci pour votre aide.

    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
     
    CREATE TABLE [dbo].[SITE_Information_Membre](
    	[Id_Info_Membre] [int] IDENTITY(1,1) NOT NULL,
    	[UserId] [uniqueidentifier] NOT NULL,
    	[Id_Info_Formulaire] [int] NULL,
    	[Valeur_Info] [varchar](1000) NULL,
    ) ON [PRIMARY]
     
    INSERT INTO dbo.SITE_Information_Membre (UserId, Id_InfoFormulaire, Valeur_Info)   VALUES (65BB1386-FA7B-4938-A9F0-1853C8998F8C,1,1)
    INSERT INTO dbo.SITE_Information_Membre (UserId, Id_InfoFormulaire, Valeur_Info)   VALUES (65BB1386-FA7B-4938-A9F0-1853C8998F8C,2,4)
    INSERT INTO dbo.SITE_Information_Membre (UserId, Id_InfoFormulaire, Valeur_Info)   VALUES (FB59EA47-DEC6-4047-89A4-A955A358208A,1,1)
    INSERT INTO dbo.SITE_Information_Membre (UserId, Id_InfoFormulaire, Valeur_Info)   VALUES (FB59EA47-DEC6-4047-89A4-A955A358208A,2,3)
    INSERT INTO dbo.SITE_Information_Membre (UserId, Id_InfoFormulaire, Valeur_Info)   VALUES (74D5620B-AF20-465E-80BD-291E5CF9E9E7,1,2)
    INSERT INTO dbo.SITE_Information_Membre (UserId, Id_InfoFormulaire, Valeur_Info)   VALUES (74D5620B-AF20-465E-80BD-291E5CF9E9E7,2,1)
    INSERT INTO dbo.SITE_Information_Membre (UserId, Id_InfoFormulaire, Valeur_Info)   VALUES (A2E43A62-7A77-4616-B8C0-C97C5830537F,1,2)
    INSERT INTO dbo.SITE_Information_Membre (UserId, Id_InfoFormulaire, Valeur_Info)   VALUES (A2E43A62-7A77-4616-B8C0-C97C5830537F,2,2)

  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 : 44
    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
    Par défaut
    Bonjour,

    Effectivement la clause PIVOT n'est utilisable que pour des calculs agrégés (COUNT, SUM, AVG, ...). Rappelez-vous que celle-ci est purement cosmétique, que donc cette logique doit donc être déplacée vers l'application, et qu'en plus l'utilisation cette clause est contre-performante.

    Je n'ai pas compris le résultat que vous cherchez à obtenir, puisque l'information Valeur_info dépend de la valeur de Id_Info_Formulaire.
    Pouvez-vous préciser ?

    @++

  3. #3
    Membre expérimenté
    Avatar de zooffy
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Août 2004
    Messages
    3 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Bâtiment

    Informations forums :
    Inscription : Août 2004
    Messages : 3 895
    Par défaut
    Merci pour ton aide.

    L'idée est d'avoir des informations sur les membres inscrits dans le site. Pour l'exemple j'ai simplifié en ne prenant que deux informations : le sexe et le statut. Mon système global me permet de fabriquer un formulaire demandant le sexe et le statut d'un membre, mais en ajoutant un simple parametre dans une table, je rajoute une information supplémentaire (la ville par exemple).

    J'ai programmé des méthode pour gérer facilement l'affichage et l'enregistrement des informations, tout ça fontionne bien.

    Maintenant il faut que je puisse lancer une recherche sur l'ensemble des membre du site, par exemple : la liste de tous les membres de sexe "Féminin" et de statut "Célibataire". Donc tout ceux qui ont un Id_Info_Formulaire = à 1 et une Valeur_Info = 4. Et ça, j'y arrive pas.

    Est ce que mon exposé est plus calir ?

  4. #4
    Membre expérimenté
    Avatar de zooffy
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Août 2004
    Messages
    3 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Bâtiment

    Informations forums :
    Inscription : Août 2004
    Messages : 3 895
    Par défaut
    Bon, je pense que l'histoire du Pivot, c'est pas trés bon, même ça paraissait séduisant au départ.

    Du coup, j'ai réinventé un pivot pour moi, mais j'ai trés peur aux performances

    Je vous soumets mon code à la fin du message.
    L'idée est de faire des SELECT sur chaque champ de formulaire et de les joindre pour retourner une table avec l'idetifiant du membre et ses info à la suite. Sauf que je vais appeler la même table un paquet de fois avec une clause WHERE différentes. Alors comment faire pour optimiser ça ?

    Pour l'instant j'ai 5 lignes dans ma table, alors ça roule, mais en prod, je compte bien avoir quelques milliers de lignes, alors je pense qu'il faut que je place des index, mais j'hésites :
    - un index sur le UserId, ça me parait évident
    - un index sur le champ de formulaire (Id_Info_Formulaire) est ce bien une bonne idée ?

    Merci pour votre aide.


    PS : j'ai fait des LEFT pour obtenir les valeurs vides car elles ne sont pas exprimées dans un enregistrement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT TSexe.UserId, TSexe.Valeur_Info AS Sexe, Stat.Valeur_Info AS Statut, TVille.Valeur_Info AS Ville,
    TVide.Valeur_Info AS Vide
     
    FROM (SELECT * FROM dbo.SITE_Information_Membre BASE WHERE Id_Info_Formulaire = 1) AS TSexe
    LEFT JOIN (SELECT * FROM dbo.SITE_Information_Membre BASE WHERE Id_Info_Formulaire = 2) AS Stat
    	ON Stat.UserId = TSexe.UserId
    LEFT JOIN (SELECT * FROM dbo.SITE_Information_Membre BASE WHERE Id_Info_Formulaire = 3) AS TVille
    	ON TVille.UserId = TSexe.UserId
    LEFT JOIN (SELECT * FROM dbo.SITE_Information_Membre BASE WHERE Id_Info_Formulaire = 30) AS TVide
    	ON TVide.UserId = TSexe.UserId

  5. #5
    Membre expérimenté
    Avatar de zooffy
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Août 2004
    Messages
    3 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Bâtiment

    Informations forums :
    Inscription : Août 2004
    Messages : 3 895
    Par défaut
    Je viens de penser à un truc : si je spécifie mes noms de champ à la place de mes SELECT *, c'est plus performant ?

    Et bien sûr, je ne prends que les champs qui m'interresse.

  6. #6
    Membre Expert Avatar de Jinroh77
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2006
    Messages
    1 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Février 2006
    Messages : 1 964
    Par défaut
    Ce sera toujours plus performant de proscrire les Select * au profit des Select <Uniquement les nécessaires>. Il y aura moins de données à rapatrier, à la fois pour le moteur SQL et sur le réseau pour atteindre votre client.

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

Discussions similaires

  1. Sql server requête pivot sans somme
    Par merlin3d dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 12/03/2010, 11h19
  2. Dimension titres de chapitre sans toucher aux autres polices
    Par profilien dans le forum Mise en forme
    Réponses: 1
    Dernier message: 24/08/2007, 17h34
  3. Réponses: 2
    Dernier message: 31/07/2007, 15h53
  4. jouer un sons sans stopper l'autre
    Par darkmalak01 dans le forum Langage
    Réponses: 2
    Dernier message: 14/10/2005, 23h54
  5. Afficher un message sans bloquer les autres traitements??
    Par Ben_Le_Cool dans le forum Langage
    Réponses: 7
    Dernier message: 13/10/2005, 00h21

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