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 :

Comment réaliser un pivot de deux colonnes ?


Sujet :

Développement SQL Server

  1. #1
    Membre averti
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Novembre 2015
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2015
    Messages : 57
    Par défaut Comment réaliser un pivot de deux colonnes ?
    Bonjour,

    Je souhaite réaliser un pivot de deux colonnes en SQL SERVER v.15, mais je n'y parviens pas. Enfin presque, j'ai trouvé des solutions, mais je n'aime pas la façon dont je l'ai codé, je suis persuadé que l'on peut réaliser cela bien mieux.

    J'ai bien entendu chercher sur Internet, mais ne suis pas parvenu à trouver de réponse (ou alors, je ne suis pas doué ).

    J'explique ma problématique :

    J'ai la table suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    create table TB 
    (
      PRODUIT CHAR(3) not null ,
      ANNEE   INT     not null ,
      QTE     INT     not null ,
      COUT    INT     not null
    ) ;
    Alimentée comme ceci :

    Nom : Table.jpg
Affichages : 140
Taille : 20,6 Ko

    Et je voudrais obtenir ceci :

    Nom : Table_pivotee.jpg
Affichages : 139
Taille : 21,8 Ko

    Avec les instructions suivantes, je parviens à réaliser le pivot d'une seule colonne mais séparément :

    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
    23
    select PRODUIT                     ,
           max( [2021] ) as QTE_ANNEE_1 , 
           max( [2022] ) as QTE_ANNEE_2 , 
           max( [2023] ) as QTE_ANNEE_3
    from
    (
      select PRODUIT , ANNEE , QTE , COUT
      from TB 
    ) as DONNEES_SOURCES
    pivot ( max( QTE ) for ANNEE in ( [2021] , [2022] , [2023] ) ) as PIVOT_QTE
    group by PRODUIT ;
     
    select PRODUIT                       ,
           max( [2021] ) as COUT_ANNEE_1 , 
           max( [2022] ) as COUT_ANNEE_2 , 
           max( [2023] ) as COUT_ANNEE_3
    from
    (
      select PRODUIT , ANNEE , QTE , COUT
      from TB 
    ) as DONNEES_SOURCES
    pivot ( max( COUT ) for ANNEE in ( [2021] , [2022] , [2023] ) ) as PIVOT_COUT
    group by PRODUIT ;
    En solution, je peux concaténer QTE et COUT pour réaliser le pivot et les déconcaténer ensuite, ça fait le job, mais c'est pas terrible en qualité de codage.

    J'ai aussi trouvé une solution en imbriquant le premier pivot en source du second comme ceci :

    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
    23
    24
    25
    select PRODUIT                             ,
           max( COUT_ANNEE_1 ) as COUT_ANNEE_1 ,
           max( COUT_ANNEE_2 ) as COUT_ANNEE_2 ,
           max( COUT_ANNEE_3 ) as COUT_ANNEE_3 ,
           max( [2021]       ) as QTE_ANNEE_1  , 
           max( [2022]       ) as QTE_ANNEE_2  , 
           max( [2023]       ) as QTE_ANNEE_3
    from
    (
      select PRODUIT                       ,
             ANNEE_2                       ,
             QTE                           ,
             max( [2021] ) as COUT_ANNEE_1 , 
             max( [2022] ) as COUT_ANNEE_2 , 
             max( [2023] ) as COUT_ANNEE_3
      from
      (
        select PRODUIT , ANNEE as ANNEE_1 , ANNEE as ANNEE_2 , QTE , COUT
        from TB 
      ) as DONNEES_SOURCES_1
      pivot ( max( COUT ) for ANNEE_1 in ( [2021] , [2022] , [2023] ) ) as PIVOT_COUT
      group by PRODUIT , ANNEE_2 , QTE
    ) as DONNEES_SOURCES_2
    pivot ( max( QTE ) for ANNEE_2 in ( [2021] , [2022] , [2023] ) ) as PIVOT_QTE
    group by PRODUIT ;
    Mais je ne suis pas encore satisfait, J'aimerai réaliser quelque chose qui ressemble à ceci :

    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
    select PRODUIT                                  ,
           max( PIVOT_QTE.[2021]  ) as QTE_ANNEE_1  , 
           max( PIVOT_QTE.[2022]  ) as QTE_ANNEE_2  , 
           max( PIVOT_QTE.[2023]  ) as QTE_ANNEE_3  ,
           max( PIVOT_COUT.[2021] ) as COUT_ANNEE_1 , 
           max( PIVOT_COUT.[2022] ) as COUT_ANNEE_2 , 
           max( PIVOT_COUT.[2023] ) as COUT_ANNEE_3
    from
    (
      select PRODUIT , ANNEE , QTE , COUT
      from TB 
    ) as DONNEES_SOURCES
    pivot ( max( QTE  ) for ANNEE in ( [2021] , [2022] , [2023] ) ) as PIVOT_QTE
    pivot ( max( COUT ) for ANNEE in ( [2021] , [2022] , [2023] ) ) as PIVOT_COUT
    group by PRODUIT ;
    Bien entendu, ça ne fonctionne pas. Auriez-vous une idée, SVP ?

    D'avance Merci de l'attention que vous porterez à ma demande.

    Cordialement,

    GiDu

  2. #2
    Membre Expert
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 169
    Par défaut
    Bonjour,

    Tu peux mettre tes 2 agrégats dans le même PIVOT:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pivot ( max( QTE ) as PIVOT_QTE, max( COUT) as PIVOT_COUT for ANNEE in ( [2021] , [2022] , [2023] ))

  3. #3
    Membre averti
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Novembre 2015
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2015
    Messages : 57
    Par défaut
    Merci pour la proposition. Hélas, j'ai essayé mais ça ne fonctionne pas :

    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
    select PRODUIT                                  ,
           max( PIVOT_QTE.[2021]  ) as QTE_ANNEE_1  , 
           max( PIVOT_QTE.[2022]  ) as QTE_ANNEE_2  , 
           max( PIVOT_QTE.[2023]  ) as QTE_ANNEE_3  ,
           max( PIVOT_COUT.[2021] ) as COUT_ANNEE_1 , 
           max( PIVOT_COUT.[2022] ) as COUT_ANNEE_2 , 
           max( PIVOT_COUT.[2023] ) as COUT_ANNEE_3
    from
    (
      select PRODUIT , ANNEE , QTE , COUT
      from TB 
    ) as DONNEES_SOURCES
    pivot ( max( QTE  ) as PIVOT_QTE , 
            max( COUT ) as PIVOT_COUT 
            for ANNEE in ( [2021] , [2022] , [2023] ) )
    group by PRODUIT ;
    SQL Error [156] [S0001]: Syntaxe incorrecte vers le mot clé 'as'.
    C'est le "as" de pivot ( max( QTE ) as PIVOT_QTE , qui apparemment pose problème. MAis j'ai peut-être mal interprété la solution proposée ?

  4. #4
    Membre Expert
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 169
    Par défaut
    En regardant la documentation plutôt brouillon de SQL Server sur le PIVOT, j'ai l'impression qu'on ne peut pivoter qu'une seule colonne, LOL:

    https://learn.microsoft.com/en-us/sq...l-server-ver16

    Je lis ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <aggregation function>(<column being aggregated>)
    Mais comme la page n'explique pas en détail cette syntaxe, je conjecture qu'une seule colonne est possible?

    Dans Oracle c'est possible, je pensais que c'était standard l'opérateur PIVOT mais il semblerait que non, désolé.

  5. #5
    Membre averti
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Novembre 2015
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2015
    Messages : 57
    Par défaut
    J'avais lu cette documentation et effectivement, elle ne parlait pas de pivot multi colonnes. C'est pour cela que je sollicitais le forum dans l'espoir qu'il y ait une autre solution.

    Je vais donc devoir me contenter de la solution que j'ai trouvé

    Je laisse encore un peu le message ouvert sur le forum au cas où une autre âme proposerait quelque chose.

    Encore Merci.

    GiDu

  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Il semblerait qu'on ait eu un petit rollback sur le forum, je vais reposter ma réponse.

    Sur SQL-Server, en effet le mieux reste de passer par la syntaxe classique qui est aussi la plus longue à écrire :
    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
      select PRODUIT
           , max(case ANNEE when 2021 then QTE  end) as QTE_2021
           , max(case ANNEE when 2022 then QTE  end) as QTE_2022
           , max(case ANNEE when 2023 then QTE  end) as QTE_2023
           , max(case ANNEE when 2021 then COUT end) as COUT_2021
           , max(case ANNEE when 2022 then COUT end) as COUT_2022
           , max(case ANNEE when 2023 then COUT end) as COUT_2023
        from TB
    group by PRODUIT
    order by PRODUIT;
     
    PRODUIT  QTE_2021  QTE_2022  QTE_2023  COUT_2021  COUT_2022  COUT_2023
    -------  --------  --------  --------  ---------  ---------  ---------
    AAA             1         2         3         11         22         33
    BBB             4         5         6         44         55         66
    CCC             7         8         9         77         88         99
    En aparté parce que je vous ai vu faire cette erreur, l'opérateur PIVOT effectue déjà un agrégat, pas la peine d'en rajouter un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    select PRODUIT
         , [2021] as QTE_2021
         , [2022] as QTE_2022
         , [2023] as QTE_2023
      from (select PRODUIT, ANNEE, QTE from TB) as t 
     pivot (max(QTE) for ANNEE in ([2021], [2022], [2023])) as PIVOT_QTE;
     
    PRODUIT  QTE_2021  QTE_2022  QTE_2023
    -------  --------  --------  --------
    AAA             1         2         3
    BBB             4         5         6
    CCC             7         8         9

  7. #7
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 995
    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 995
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par vanagreg Voir le message
    Dans Oracle c'est possible, je pensais que c'était standard l'opérateur PIVOT mais il semblerait que non, désolé.
    Non PIVOT n'existe pas dans le SQL car c'est de la cosmétique...

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  8. #8
    Membre averti
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Novembre 2015
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2015
    Messages : 57
    Par défaut
    Bonjour,

    Merci pour tous vos retours et conseil de programmation.

    GiDu

  9. #9
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Non PIVOT n'existe pas dans le SQL car c'est de la cosmétique...
    Pas d'accord : c'est de la cosmétique en OLTP où une base de données fait de la base de données et relativement peu de traitement.
    En analytique, c'est très important.
    Les modèles de machine learning par exemple utilisent des données en entrée quasiment toujours pivotées.
    À partir du moment où le SGBD devient un moteur de traitement de la données, ce n'est plus cosmétique.
    Ça rentrera dans la norme dans le futur pour sûr.

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

Discussions similaires

  1. Requête pivot sur deux colonnes
    Par Caillou63 dans le forum Développement
    Réponses: 5
    Dernier message: 16/05/2012, 19h49
  2. Comment faire un tableau avec deux colonnes à 50 % ?
    Par coolben dans le forum Android
    Réponses: 2
    Dernier message: 22/12/2010, 16h07
  3. comment ecrire un article en deux colonnes
    Par homam dans le forum Mise en forme
    Réponses: 3
    Dernier message: 20/04/2009, 14h59
  4. Pivot de deux colonnes de tables différentes
    Par badi3a82 dans le forum Développement
    Réponses: 5
    Dernier message: 22/10/2008, 13h12
  5. Comment réaliser une liste déroulante à deux niveaux !?
    Par Dubbiker dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 01/07/2007, 11h51

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