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

Langage SQL Discussion :

Requête pour transposer les données


Sujet :

Langage SQL

  1. #1
    Membre du Club
    Inscrit en
    Avril 2007
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 106
    Points : 46
    Points
    46
    Par défaut Requête pour transposer les données
    Bonjour, j'ai une requête sql:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    select h.matri,h.cohis,h.his01,h.his02,h.his03,h.his04,h.his05,h.his06,h.his07,h.his08,h.his09,h.his10,h.his11,h.his12 from t1 h, t2 p 
    where (h.matri=p.matri) and  (h.annee='23') and (h.corub='014') and (p.p023='7')
    qui me donne les résultats suivants:
    Nom : Resultat_requete.jpg
Affichages : 145
Taille : 334,5 Ko

    Les colonnes où il y'a une valeur différente de zéro à la fois pour COHIS=30 et COHIS=40 sont celle que je veux capter par matricule. Je souhaite donc avoir le résultat final ci après:

    Nom : Reslutat_souhaité.jpg
Affichages : 130
Taille : 70,1 Ko

    Pouvez vous svp m'aider ? Je ne sais pas si c'est possible de la faire en SQL. Je galère depuis un certain temps.

    Par avance Merci de votre aide.

  2. #2
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    776
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 776
    Points : 1 488
    Points
    1 488
    Par défaut
    Bonjour,

    Il eut été plus simple de présenter les tables plutôt que la requête ^^
    Ensuite, les jointures dans la clause WHERE est une écriture qui est postérieure à 1992. Il serait temps de changer les habitudes !

    Dans le même registre, une modélisation de donnée qui en arrive à avoir des colonnes numérotées est symptomatique d'une erreur.

    Ceci dit, avec les informations fournies, votre requête devrait ressembler à ceci (revoir les colonnes alimentant les colonnes de date)
    select h.matri
    ,h.cohis
    ,case when h.cohis in (30,40)
    then coalesce(nullif(h.his01,0), nullif(h.his02,0), nullif(h.his03,0), nullif(h.his04,0)) as date_entree
    ,case when h.cohis in (30,40)
    then coalesce(nullif(h.his05,0), nullif(h.his06,0), nullif(h.his07,0), nullif(h.his08,0)) as date_sortie
    from t1 h inner join t2 p on h.matri=p.matri
    where (h.annee='23')
    and (h.corub='014')
    and (p.p023='7')
    -- and (h.cohis in (30,40)
    ;
    Le savoir est une nourriture qui exige des efforts.

  3. #3
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    776
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 776
    Points : 1 488
    Points
    1 488
    Par défaut
    Oups, désolé, je n'avais pas vu que le code 30 était pour la date d'entrée et le code 40 pour la date de sortie.
    => faut vraiment adapter la rq que je vous ais fourni.

    Essayez par vous même.
    Au pire, redemandez de l'aide, en précisant le SGBD utilisé (et la version)
    Le savoir est une nourriture qui exige des efforts.

  4. #4
    Membre du Club
    Inscrit en
    Avril 2007
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 106
    Points : 46
    Points
    46
    Par défaut
    Bonjour,

    Je reviens à nouveau demander votre aide car je n'arrive pas à adapter la requête. Pouvez vous m'aider svp ? C'est sur db2.

  5. #5
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    776
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 776
    Points : 1 488
    Points
    1 488
    Par défaut
    Citation Envoyé par lesultan2007 Voir le message
    je n'arrive pas à adapter la requête.
    C'est sur db2.
    Bon DB2, c'est pas dans mes compétences => faire confiance aux autres contributeurs

    Pouvez-vous expliquer ce que contiennent les colonnes :
    • cohis (surtout ce que représentent les valeurs 30 et 40)
    • h.his01,h.his02,h.his03,h.his04,h.his05,h.his06,h.his07,h.his08,h.his09,h.his10,h.his11,h.his12
      • pourquoi les n° ?
      • en quoi sont elles différentes ?
      • que sont les valeurs ?
    Le savoir est une nourriture qui exige des efforts.

  6. #6
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 951
    Points : 4 376
    Points
    4 376
    Par défaut
    Pas de DB2 sous la main, mais vous pouvez vous inspirer de ceci quite à changer quelques fonctions :

    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
    with data(matri,cohis,his01,his02,his03,his04,his05,his06,his07,his08,his09,his10,his11,his12) as
    (
    	select 130669, 30, 30622, 30622, 0, 30622, 0, 10623, 10623, 10623, 10623, 10623, 10623, 10623 union all
    	select 130669, 40,     0, 10223, 0, 10223, 0,     0,     0,     0,     0,     0,     0,     0 union all 
     
     
    	select 131008, 30, 10922, 10922, 10922, 10922, 10922, 10922,      0,     0,     0, 21023, 21023, 21023 union all
    	select 131008, 40,     0,     0,     0,     0,     0, 310523,     0,     0,     0,     0,     0,     0 -- union all 
     
    )
    select 
    	d.matri,
    	coalesce ( 
    			nullif(d.his01,0), nullif(d.his02,0), nullif(d.his03,0), nullif(d.his04,0), nullif(d.his05,0), nullif(d.his06,0),    
    			nullif(d.his07,0), nullif(d.his08,0), nullif(d.his09,0), nullif(d.his10,0), nullif(d.his11,0), nullif(d.his12,0)     
    		) as date_from,
    	coalesce( 
    		nullif(d1.his01, 0),  nullif(d1.his02, 0), nullif(d1.his03, 0), nullif(d1.his04, 0),  nullif(d1.his05, 0), nullif(d1.his06, 0),
    			nullif(d1.his07, 0),  nullif(d1.his08, 0), nullif(d1.his09, 0), nullif(d1.his10, 0),  nullif(d1.his11, 0), nullif(d1.his12, 0) 
    		) as date_to
    from data d
    join data d1 on d.matri = d1.matri and d.cohis = 30 and d1.cohis = 40
    ;

  7. #7
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    776
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 776
    Points : 1 488
    Points
    1 488
    Par défaut
    La réponse de JeitEmgie n'est exacte que si la valeur recherchée est la 1ere valeur non égale à 0 dans l'ordre des colonnes.

    Si le besoin est de trouver la plus grande/petite valeur sur l'ensemble des colonnes c'est autre chose.
    D'où les questions sur le contenu
    Le savoir est une nourriture qui exige des efforts.

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 239
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 239
    Points : 12 869
    Points
    12 869
    Par défaut
    Bonjour,
    Je vois bien une requête de ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Select t1.id,
    (Case when t1.his01 <>0 and t2.his01 <> 0 then t1.his01
    When t1.his02 <>0 and t2.his02 <> 0 then t1.his02
    ...
    ) as date_from,
    ... Idem pour la date_to...
    From LaTable as t1
    Inner Join LaTable as t2
    On t1.Matri = t2.Matri
    Where t1.Cohis = 30 and t2.Cohis = 40
    Tatayo

  9. #9
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 951
    Points : 4 376
    Points
    4 376
    Par défaut
    Citation Envoyé par Michel.Priori Voir le message
    La réponse de JeitEmgie n'est exacte que si la valeur recherchée est la 1ere valeur non égale à 0 dans l'ordre des colonnes.

    Si le besoin est de trouver la plus grande/petite valeur sur l'ensemble des colonnes c'est autre chose.
    D'où les questions sur le contenu
    Oops, erreur de transcription
    il manque
    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
    and 
    			(
    			d.his01 <> d1.his01 and d1.his01 <> 0
    			or d.his02 <> d1.his02 and d1.his02 <> 0
    			or d.his03 <> d1.his03 and d1.his03 <> 0
    			or d.his04 <> d1.his04 and d1.his04 <> 0
    			or d.his05 <> d1.his05 and d1.his05 <> 0
    			or d.his06 <> d1.his06 and d1.his06 <> 0
    			or d.his07 <> d1.his07 and d1.his07 <> 0
    			or d.his08 <> d1.his08 and d1.his08 <> 0
    			or d.his09 <> d1.his09 and d1.his09 <> 0
    			or d.his10 <> d1.his10 and d1.his10 <> 0
    			or d.his11 <> d1.his11 and d1.his11 <> 0
    			or d.his12 <> d1.his12 and d1.his12 <> 0
    		)
    dans la condition du join...

  10. #10
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 299
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 299
    Points : 39 635
    Points
    39 635
    Billets dans le blog
    9
    Par défaut
    @JeitEmgie : une condition de jointure ayant plein de OR et des conditions "différent de" n'est pas sargable, les performances seront catastrophiques dès que le volume sera un tant soit peu significatif


    @lesultan2007 : pourquoi une même personne représentée par un même matricule peut avoir plusieurs valeurs de dates d'entrée et plusieurs valeurs de dates de sortie ?
    Non seulement la présence de 12 colonnes est symptomatique d'une erreur de modélisation, mais en plus, les dates ne sont visiblement pas de type date...
    Une base de données mal conçue est la source de tous les maux : requêtes complexes, peu performantes, données redondantes et dont l'intégrité est douteuse, accès concurrents dégradés, etc.

  11. #11
    Membre du Club
    Inscrit en
    Avril 2007
    Messages
    106
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 106
    Points : 46
    Points
    46
    Par défaut
    Citation Envoyé par Michel.Priori Voir le message
    Bon DB2, c'est pas dans mes compétences => faire confiance aux autres contributeurs

    Pouvez-vous expliquer ce que contiennent les colonnes :
    • cohis (surtout ce que représentent les valeurs 30 et 40)
    • h.his01,h.his02,h.his03,h.his04,h.his05,h.his06,h.his07,h.his08,h.his09,h.his10,h.his11,h.his12
      • pourquoi les n° ?
      • en quoi sont elles différentes ?
      • que sont les valeurs ?
    Bonjour, nous avons hérité d'une base de données à notre arrivée dans l'entreprise. Elle existe depuis les années 1990. Il faut une refonte c'est sûr on y réfléchit mais pour l'heure il nous faut trouver la solution au problème. En fait c'est une base de données qui enregistre la rémunération des travailleurs saisonniers. Sachant qu'un saisonnier, il peut avoir 2 contrats dans l'année. Un contrat est matérialisé par une date d'entrée et une date de sortie. Les lignes où cohis =30 représente les dates d'entrée qui ont été historisées et celles où cohis=40 représente les dates de sorties qui sont historisées.

    Là nous devons ressortir pour chaque employé, ses différentes dates d'entrées et de sorties sur une période donnée. ET c'est là où nous rencontrons la difficulté à organiser les données. Je pense que le type de base de données n'est pas un problème. Je peux très bien pour les besoins de ce travail grâce à un lot ssis transférer les données dans une base sql serveur si vous êtes plus à l'aise avec sql serveur.

    Enfin les numéros his01, his02, his12 représente les mois de Janvier Février ... jusqu'à décembre. Là où pour Hisnn, on a un evaleur à la fois pour cohis=30 et cohis=40 cela correspond aux dates d'entrée et de sortie d'un contrat.

    Par avance Merci de votre aide.

  12. #12
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 951
    Points : 4 376
    Points
    4 376
    Par défaut
    Citation Envoyé par lesultan2007 Voir le message
    Là nous devons ressortir pour chaque employé, ses différentes dates d'entrées et de sorties sur une période donnée. ET c'est là où nous rencontrons la difficulté à organiser les données. Je pense que le type de base de données n'est pas un problème. Je peux très bien pour les besoins de ce travail grâce à un lot ssis transférer les données dans une base sql serveur si vous êtes plus à l'aise avec sql serveur.
    Faites-le et profitez-en pour changer de modèle : (matri, cohis, his, mois) ...

  13. #13
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    776
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 776
    Points : 1 488
    Points
    1 488
    Par défaut
    Citation Envoyé par lesultan2007 Voir le message
    Les lignes où cohis =30 représente les dates d'entrée qui ont été historisées et celles où cohis=40 représente les dates de sorties qui sont historisées.
    ...
    Enfin les numéros his01, his02, his12 représente les mois de Janvier Février ... jusqu'à décembre. Là où pour Hisnn, on a un evaleur à la fois pour cohis=30 et cohis=40 cela correspond aux dates d'entrée et de sortie d'un contrat.
    Pouvez-vous préciser le sens des "valeurs" de de Hisnn ?

    Ce que je comprends, c'est que 0 = pas de valeur.
    Mais quand il y en a une, que représente t'elle ?
    et pourquoi il y en a plusieurs sur la même ligne ? dans le cas d'une embauche en janvier, pas besoin d'avoir une valeur en février ...

    En attendant votre retour, on peut jouer avec les CTE pour essayer d'y voir plus clair :

    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
    31
    32
    33
     
    With cte as 
    (select h.matri ,case h.cohis when 30 then 'entrée' when 40 then 'sortie' else null end as mouvement,h.his01,h.his02,h.his03,h.his04,h.his05,h.his06,h.his07,h.his08,h.his09,h.his10,h.his11,h.his12 
    from t1 h join t2 p on (h.matri=p.matri)
    where  (h.annee='23') 
      and (h.corub='014') 
      and (p.p023='7')
    )
    select matri, mouvement, case h.his01 when 0 then null else h.his01 end as valeur, case h.his01 when 0 then null else 1 end as mois
    union all
    select matri, mouvement, case h.his02 when 0 then null else h.his02 end as valeur, case h.his02 when 0 then null else 2 end as mois
    union all
    select matri, mouvement, case h.his03 when 0 then null else h.his03 end as valeur, case h.his03 when 0 then null else 3 end as mois
    union all
    select matri, mouvement, case h.his04 when 0 then null else h.his04 end as valeur, case h.his04 when 0 then null else 4 end as mois
    union all
    select matri, mouvement, case h.his05 when 0 then null else h.his05 end as valeur, case h.his05 when 0 then null else 5 end as mois
    union all
    select matri, mouvement, case h.his06 when 0 then null else h.his06 end as valeur, case h.his06 when 0 then null else 6 end as mois
    union all
    select matri, mouvement, case h.his07 when 0 then null else h.his07 end as valeur, case h.his07 when 0 then null else 7 end as mois
    union all
    select matri, mouvement, case h.his08 when 0 then null else h.his08 end as valeur, case h.his08 when 0 then null else 8 end as mois
    union all
    select matri, mouvement, case h.his09 when 0 then null else h.his09 end as valeur, case h.his09 when 0 then null else 9 end as mois
    union all
    select matri, mouvement, case h.his10 when 0 then null else h.his10 end as valeur, case h.his10 when 0 then null else 10 end as mois
    union all
    select matri, mouvement, case h.his11 when 0 then null else h.his11 end as valeur, case h.his11 when 0 then null else 11 end as mois
    union all
    select matri, mouvement, case h.his12 when 0 then null else h.his12 end as valeur, case h.his12 when 0 then null else 12 end as mois
     
    order by matri, mois, mouvement
    Le savoir est une nourriture qui exige des efforts.

Discussions similaires

  1. [XL-2010] Transposer les donnés de plusieurs cellules dans une seule et même cellule
    Par vbaétude dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 11/07/2019, 11h43
  2. [Toutes versions] Macro pour transposer les donnees d'un tableau excel
    Par Loupion dans le forum Excel
    Réponses: 2
    Dernier message: 20/09/2017, 12h29
  3. Réponses: 11
    Dernier message: 06/10/2016, 11h13
  4. Réponses: 4
    Dernier message: 06/08/2012, 15h49
  5. [XL-2007] Macro pour transposer les colonnes en lignes
    Par boubadia dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 19/10/2011, 20h51

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