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 :

Besoin d'aide pour une requète compliquée


Sujet :

SQL Oracle

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 145
    Points : 77
    Points
    77
    Par défaut Besoin d'aide pour une requète compliquée
    Bonjour tout le monde, je suis nouveau sur ce forum.
    Je vais essayer de vous expliquer mon problème clairement.
    J'ai deux tables, une table VERSION avec comme champs unt_idt, ver_idt, typ_unt, lib_unt etc... et une autre table TYPE_UNITE avec les champs typ_unt, cat_cod.

    Les unités sont structurées en catégories Mere, Fille (cat_cod) et ces catégories ont plusieurs types d'unité (typ_unt).
    Table TYPE_UNITE
    typ_unt cat_cod
    esp | fille
    esg | fille
    ues | fille
    lep | mere
    lap | mere
    etc...

    Dans ma table version pour chaque changement sur une unité il y a une incrémentation de la version (ver_idt). Un changement de libellé ou de type etc.
    Donc pour une unité je peux avoir plusieurs enregistrements:
    unt_idt | ver_idt | typ_unt | lib_unt
    126 | 1 | esp | test 1
    126 | 2 | esp | test 2
    126 | 3 | le | test 2

    Je voulais savoir comment m'y prendre pour ramener pour chaque unité le numéro de la version (ver_idt) ou un changement de catégorie, si y en a un, a été fait?
    Dans mon exemple le numéro serait ver_idt = 3. Mais comment bouclé sur les enregistrements d'un id (unt_idt)? reperer si sur un champs (typ_unt) y a un changement et récupérer la valeur d'un autre champs (ver_idt)?

    Si quelqu'un peut m'aider ca serait génial!
    Merci d'avance en tout cas.

  2. #2
    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
    J'ai du mal à suivre votre besoin, essayez de représenter aussi ce que vous attendez en résultat.

    Précisez également votre version d'Oracle.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 145
    Points : 77
    Points
    77
    Par défaut
    Bonjour je vais essayer d'etre plus clair. J'ai une table VERSION avec ces champs: ID, VER_IDT, TYP_UNT
    Pour une unité j'ai donc ca:
    ID:126 VER_IDT:1 TYP_UNT: ESP
    ID:126 VER_IDT:2 TYP_UNT: ESP
    ID:126 VER_IDT:3 TYP_UNT: USL
    Une autre:

    ID:127 VER_IDT:1 TYP_UNT: ESP
    ID:127 VER_IDT:2 TYP_UNT: ESP
    ID:127 VER_IDT:3 TYP_UNT: EPP
    ID:127 VER_IDT:4 TYP_UNT: ESP
    ID:127 VER_IDT:5 TYP_UNT: USL
    Et ainsi de suite...
    Comment pour chaque unité, donc chaque ID, récupérer le numéro de version VER_IDT ou le champs TYP_UNT a été changé?

    Dans le cas de l'unité 126 le numéro de version qui correspond au
    changement du champs TYP_UNT c'est le 3
    Dans le cas de l'unité 127 le numéro de version qui correspond au changement du champs TYP_UNT c'est le 5

    J'espère avoir été plus clair, ma version d'Oracle est la 10g.

    Merci d'avance pour votre aide!

  4. #4
    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
    C'est un peu plus clair, quelques questions encore.

    Pourquoi sur le 127 seule la version 5 est retenue ?
    Les versions 3 et 4 elles aussi ont changé de type par rapport au précédent.

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 145
    Points : 77
    Points
    77
    Par défaut
    Oui oui pardon je me suis trompé, bien vu, sur la 127 il faudrait donc récupérer la version 3, 4 et 5 puisque le champs TYP_UNT a changé.

    Déjà avec un changement je trouve ca compliqué à gérer, mais on me demande pour tout changement. Donc dans le cas de la 127 je devrais ramener les versions 3, 4 et 5. Et la 3 pour la 126 et si aucun changement pour une unité ne rien ramener forcément...

    Bref je suis completement perdu...

    Merci de ton aide c'est super gentil!

  6. #6
    Membre confirmé

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    507
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 507
    Points : 503
    Points
    503
    Par défaut
    Avec la fonction LEAD qui permet de regarder les enregistrements suivants ou précédents, vous devriez vous en sortir.
    Le forum est plein d'exemples.

  7. #7
    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 vous êtes nouveau sur le forum je vous donne la solution :
    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
    WITH MaTable AS
    (
    select 126 as id, 1 as ver, 'ESP' as typ from dual union all
    select 126      , 2       , 'ESP'        from dual union all
    select 126      , 3       , 'USL'        from dual union all
    select 127      , 1       , 'ESP'        from dual union all
    select 127      , 2       , 'ESP'        from dual union all
    select 127      , 3       , 'EPP'        from dual union all
    select 127      , 4       , 'ESP'        from dual union all
    select 127      , 5       , 'USL'        from dual
    )
    select id, ver, typ, typ_prev
    from
        (
        select id, ver, typ,
               lag(typ, 1, typ) over(partition by id order by ver asc) as typ_prev
          from MaTable
        )
    where typ <> typ_prev
    order by id asc, ver asc;
     
    ID	VER	TYP	TYP_PREV
    126	3	USL	ESP
    127	3	EPP	ESP
    127	4	ESP	EPP
    127	5	USL	ESP

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 145
    Points : 77
    Points
    77
    Par défaut
    Merci beaucoup pour vos réponse. En fait faudrait que j'arrive à faire ca sur tous les ID et non pas seulement sur 126 et 127.

    Aussi une autre question, à la fin tu as mis :
    WHERE typ <> typ_prev

    Or typ_prev si je comprends bien est le résultat de la fonction LAG et non un champs de ma table.
    On peut dans la clause where mettre
    un champs <> résultat d'une fonction?

  9. #9
    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
    La requête ci-dessus fonctionnera pour tous vos id, comme je n'ai pas votre table sous la main je me suis cantonné à votre exemple pour démontrer que ça fonctionne.

    Vous voyez bien que nulle part dans ma requête je n'ai utilisé en dur les ID 126 ou 127 (pour vous la requête commence à SELECT id, ver, typ, typ_prev, ce qu'il y a avant ne me sert qu'à généré un jeu de données).

    Vous pouvez aliasez (donner un autre nom) n'importe quelle élément d'un select, que ce soit une colonne, un calcul, un agrégat, une fonction, une requête scalaire...

    Dans le cas présent, c'est un simple alias de fonction qui est effectué dans la sous-requête au niveau du from.

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 145
    Points : 77
    Points
    77
    Par défaut
    Merci Waldar, j'ai changé le jeu de donnée dans:
    WITH MaTable AS
    (
    etc..
    )
    Et ca marche pour le reste! C'est super!
    Je viens de comprendre le mecanisme donc c'est encore mieux!

    Merci beaucoup!

  11. #11
    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
    Il ne faut pas changer le WITH, vous n'en avez pas besoin.
    Si je reprends le nom des objets dont vous parliez dans votre premier post, exécutez directement cette requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT unt_idt, ver_idt, typ_unt, typ_prev
    FROM
        (
        SELECT unt_idt, ver_idt, typ_unt,
               lag(typ_unt, 1, typ_unt) over(partition BY unt_idt ORDER BY ver_idt ASC) AS typ_unt_prev
          FROM version
        )
    WHERE typ_unt <> typ_unt_prev
    ORDER BY unt_idt ASC, ver_idt ASC;

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 145
    Points : 77
    Points
    77
    Par défaut
    Ah oui effectivement ca marche! En fait le With ne sert à rien, alors pourquoi l'avoir mit? Je comprends plus trop du coup

    J'ai un peu du mal à comprendre le mécanisme de faire un premier select pour ramener un cerain nombre d'enregistrement qui servira de table "virtuelle" si je peux m'exprimer ainsi.

  13. #13
    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
    Parce que vous, dans votre base de données vous avez une table VERSION.

    Mais pas moi, donc je simule une petite table VERSION d'après les données que vous avez écrite ici, celà permet de démontrer que la requête fonctionne.

    N'importe qui en version 9+ qui fera un copier / coller de la requête aura le même résultat, pas besoin de débarquer dans votre entreprise !

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 145
    Points : 77
    Points
    77
    Par défaut
    Merci beaucoup Waltar en tout cas pour ton aide, tes explications, ca m'a permis de faire ce qu'on m'a demandé
    Et de comprendre ce qui est le plus important!

    Les fonctions LEAD et LAG sont geniales!

Discussions similaires

  1. Besoin d'aide pour une requête compliquée
    Par Chekov dans le forum Langage SQL
    Réponses: 2
    Dernier message: 24/01/2008, 10h59
  2. Réponses: 2
    Dernier message: 12/09/2007, 21h47
  3. Besoin d'aide pour une requête SQL
    Par Borami dans le forum Langage SQL
    Réponses: 1
    Dernier message: 07/11/2005, 10h33
  4. Besoin d'aide pour une Requête SQL ...
    Par Kokito dans le forum Requêtes
    Réponses: 2
    Dernier message: 07/07/2004, 11h56
  5. besoin d'aide pour une requête
    Par Damien69 dans le forum Langage SQL
    Réponses: 11
    Dernier message: 31/03/2004, 15h38

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