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

SQL Oracle Discussion :

Transposer une table (colonne -> ligne)


Sujet :

SQL Oracle

  1. #1
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    83
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 83
    Points : 56
    Points
    56
    Par défaut Transposer une table (colonne -> ligne)
    Bonjour,

    Je tiens d'abord à m'excuser si ce sujet a déja eu une réponse, mais ayant passé toute la matinée sur le forum je n'ai pas trouver de répons eà mon interrogation d'où la création de cette discussion;

    J'ai une table Test avec les valeur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    create table test_irf
    (
        id_pers number(11),
        mnt     number( 9)
    );
    echantillon test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    insert into test_irf values (1, 10);
    insert into test_irf values (1, 11);
    insert into test_irf values (1, 12);
    insert into test_irf values (2,  1);
    insert into test_irf values (2,  2);
    J'aimerai savoir comment transposer cette table pour obtenir
    1 | 10 | 11 | 12
    2 |  1 |  2 | null
    Je sèche !

    Merci beaucoup !

  2. #2
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Recherche pivot sur le forum, mais compte tenu de ton exemple ça ne fonctionnera pas, le SQL est un langage statique qui doit connaître à l'avance le nombre de colonne.
    Donc pivote les lignes en colonnes côté applicatif ou génère la requête pivot en déterminant précédemment le nombre de colonnes à afficher.
    Si tu dois le faire en PL/SQL regarde pivot de tkyte.

    Sinon regarde peut être du côté de String Aggregation Techniques, mais ça n'est pas du pivot.

  3. #3
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2011
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2011
    Messages : 146
    Points : 263
    Points
    263
    Par défaut
    Ok c'est un peu tordu , mais l'astuce c'est de générer un chainage entre les lignes puis de passer par une lecture hierarchique et de ne garder que le plus grand path .

    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
    26
    27
    28
    29
    30
     
    WITH test_irf
    AS
    (
    SELECT 1 AS id_pers , 10 AS mnt FROM DUAL UNION ALL
    SELECT 1            , 11        FROM DUAL UNION ALL
    SELECT 1            , 12        FROM DUAL UNION ALL
    SELECT 2            , 1         FROM DUAL UNION ALL
    SELECT 2            , 2         FROM DUAL 
    )
    SELECT id_pers||'|'||mnt_list
    FROM (
          SELECT
             id_pers,
             substr(SYS_CONNECT_BY_PATH(mnt, '|'),2) mnt_list
          FROM
             (
             SELECT id_pers,
                    mnt,
                    count(*) OVER ( partition by id_pers ) cnt,
                    ROW_NUMBER () OVER ( partition by id_pers order by mnt) seq
             FROM   test_irf
             WHERE  mnt is not null
             )
          WHERE seq=cnt
          START WITH seq=1
          CONNECT BY PRIOR seq+1 = seq
          AND PRIOR id_pers = id_pers
        )
    ;
    Il doit y avoir des façons plus propre, d'ailleurs je suis preneur
    Cordialement.

  4. #4
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    83
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 83
    Points : 56
    Points
    56
    Par défaut
    Juste une petite correction,

    le résultat attendu était plutôt de récupérer le résultats dans des colonnes différentes.

    ID_PERS  | MNT_1 | MNT_2 | MNT_3 |
    ----------------------------------
    1        | 10    | 11    |  12   |
    2        | 1     | 2     |  null |

  5. #5
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Citation Envoyé par twixi Voir le message
    le résultat attendu était plutôt de récupérer le résultats dans des colonnes différentes.
    J'avais bien compris, relis mon message !

  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Comme skuatamad vous l'a indiqué, il faut faire un pivot :
    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
    with SR as
    (
    select id_pers, mnt
         , row_number() over(partition by id_pers order by mnt asc) as rn
      from test_irf
    )
      select id_pers
           , max(case rn when 1 then mnt end) as mnt_1
           , max(case rn when 2 then mnt end) as mnt_2
           , max(case rn when 3 then mnt end) as mnt_3
        from SR
    group by id_pers
    order by id_pers asc;
     
       ID_PERS      MNT_1      MNT_2      MNT_3
    ---------- ---------- ---------- ----------
             1         10         11         12
             2          1          2

  7. #7
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    83
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 83
    Points : 56
    Points
    56
    Par défaut
    Merci beaucoup pour ta réponse skuatamad. Il n'est donc pas possible d'obtenir ce que je veux .

    A vrai dire mon problème est le suivant :


    J'ai 12 lignes par ID_PERS (1 ligne correspond à un mois) et j'aimerai donc le transposer. Le nombre de colonne est à présent fixé.

    Je voudrais créer un top=1 pour les id_pers ayant le montant > 1500 durant 3 mois consécutifs?

    Je ne vois pas comme faire là ...

  8. #8
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Salut !

    Tu peux utiliser les fonctions analytiques pour calculer sur chaque ligne une somme selon un ordre et dans un group.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SUM(mnt) OVER (PARTITON BY id_pers ORDER BY tadate ROWS 3 PRECEDING )
    Cela te donnera pour chaque ligne la somme des montants sur une fenêtre de 3 précédents.

    Ensuite, tu fais une sur-requête sur le résultat pour filtrer les lignes dont la somme cumulée est supérieure à 1500...

    (c'est ma photo)
    Paku, Paku !
    Pour les jeunes incultes : non, je ne suis pas un pokémon...

    Le pacblog : http://pacmann.over-blog.com/

  9. #9
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    83
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 83
    Points : 56
    Points
    56
    Par défaut
    Merci Waldar !
    Ton exemple réponds parfaitement à mon besoin initial !

    Merci pacmann !
    C'est exactement ce que je cherchais !

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

Discussions similaires

  1. Titre d'une table ayant plusieurs lignes et colonnes
    Par romson2 dans le forum Interfaces Graphiques en Java
    Réponses: 4
    Dernier message: 21/12/2010, 01h36
  2. Transposer une variable colonne en variable ligne
    Par AlexFred dans le forum SAS Base
    Réponses: 4
    Dernier message: 05/10/2010, 18h59
  3. Insertion des colonnes d'une table dans les lignes d'une nouvelle
    Par atlain75 dans le forum Développement de jobs
    Réponses: 4
    Dernier message: 18/02/2010, 11h04
  4. Réponses: 2
    Dernier message: 13/07/2006, 17h01
  5. [DEB.] - Transposer une table SQL en XML SCHEMA ???
    Par oulahoup dans le forum Valider
    Réponses: 2
    Dernier message: 10/06/2003, 15h11

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