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 :

Explication comportement fonctions analytiques


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    LEK
    LEK est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    715
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 715
    Par défaut Explication comportement fonctions analytiques
    Bonsoir,
    je m'essaye aux fonctions analytiques mais je rencontre quelques difficultés.
    Pour mes tests j'ai le modèle suivant décrivant différents modèles (ID_MODELE) de véhicules/machines dont plusieurs prototypes (NUM_PROTOTYPE) sont mis à l'essai dans le temps
    (à la date DATE_MEC).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    ID_MODELE	 |NUM_PROTOTYPE |	DATE_MEC
    1		 |1                       |16/09/2012
    1		 |2                       |01/01/2012
    2		 |3                       |01/01/2013
    2		 |4                       |01/09/2012
    2		 |5                       |01/08/2012
    Pour chaque modèle, en fonction de la date courante,
    je voudrais afficher le dernier numéro de prototype mis en circulation et sa date de mise en circulation ainsi
    que le prochain à mettre en circulation et sa date de mise en circulation.

    Ce qui devrait me donner le résultat suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    id_modele   |Numproto_prec       |dte_mec_prec	 |Numproto_next         |dte_mec_next
    -------------------------------------------------------------------------
    1           | 1                   |16/09/2012    |                     |
    2           | 4                   |01/09/2012    |3                    |01/01/2013
    J'ai donc écrit ma requête ainsi, mais je n'ai pas le résultat escompté :
    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 T as
    (
        select 1 id_modele, 1 num_prototype, trunc(to_date('16/09/2012','DD/MM/YYYY')) DATE_MEC from dual union
        select 1 id_modele, 2 num_prototype, trunc(to_date('01/01/2012','DD/MM/YYYY')) DATE_MEC from dual union
        select 2 id_modele, 3 num_prototype, trunc(to_date('01/01/2013','DD/MM/YYYY')) DATE_MEC from dual union
        select 2 id_modele, 4 num_prototype, trunc(to_date('01/09/2012','DD/MM/YYYY')) DATE_MEC from dual union
        select 2 id_modele, 5 num_prototype, trunc(to_date('01/08/2012','DD/MM/YYYY')) DATE_MEC from dual 
    )
    SELECT  distinct 
                   id_modele, 
                 case when (date_mec <= TRUNC (SYSDATE)) then 
                 last_value(num_prototype ) OVER (PARTITION BY id_modele ORDER BY date_mec asc, num_prototype desc )
                 else null end
                  AS Numprototype_prec
                 , 
                 case when (TRUNC (date_mec) <= TRUNC (SYSDATE)) then 
                 last_value(TRUNC(date_mec)) OVER (PARTITION BY  id_modele ORDER BY date_mec desc)
                 else null end  AS date_mec_prec,
                 case when (TRUNC (date_mec) > TRUNC (SYSDATE)) then
                  first_value(num_prototype ) OVER (PARTITION BY  id_modele ORDER BY date_mec asc, num_prototype desc ) 
                  else null end  AS Numprotonext
                 , 
                 case when (TRUNC (date_mec) > TRUNC (SYSDATE)) then
                 first_value(TRUNC(date_mec)) OVER (PARTITION BY  id_modele ORDER BY date_mec )
             else null end as date_mec_next
              FROM T;
    Mais je n'arrive pas au résultat voulu. J'ai réussi à écrire la requête en traitant la recherche du prototype passé et du prototype à venir via deux requêtes séparées mais je n'arrive pas à en faire une seule... Un oeil avisé pourrais-t-il me mettre sur la bonne voie ?

    Merci pour toute aide,
    Lek.

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

    Informations forums :
    Inscription : Août 2008
    Messages : 2 952
    Par défaut
    Tu peux tenter comme ça, mais je n'ai pas fait de tests complémentaires sur d'autres valeurs, je ne suis pas sûr que ce soit assez blindé...
    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
      WITH T AS (
    SELECT 1 id_modele, 1 num_prototype, trunc(to_date('16/09/2012','DD/MM/YYYY')) DATE_MEC FROM dual union
    SELECT 1 id_modele, 2 num_prototype, trunc(to_date('01/01/2012','DD/MM/YYYY')) DATE_MEC FROM dual union
    SELECT 2 id_modele, 3 num_prototype, trunc(to_date('01/01/2013','DD/MM/YYYY')) DATE_MEC FROM dual union
    SELECT 2 id_modele, 4 num_prototype, trunc(to_date('01/09/2012','DD/MM/YYYY')) DATE_MEC FROM dual union
    SELECT 2 id_modele, 5 num_prototype, trunc(to_date('01/08/2012','DD/MM/YYYY')) DATE_MEC FROM dual 
    ),
           t_next as (
    select id_modele, num_prototype, date_mec,
           lead(num_prototype) over (partition by id_modele order by date_mec) as next_proto,
           lead(date_mec) over (partition by id_modele order by date_mec) as next_date_mec
      from t
    )
    select id_modele, 
           max(num_prototype) keep (dense_rank first order by case when date_mec <= trunc(sysdate) 
                                                                   then date_mec 
                                                               end desc NULLS LAST) as Numproto_prec,
           max(case when date_mec <= trunc(sysdate) then date_mec end) as dte_mec_prec,
           min(next_proto) keep (dense_rank first order by case when coalesce(next_date_mec, to_date('31/12/9999','dd/mm/yyyy')) >= trunc(sysdate) 
                                                                then coalesce(next_date_mec, to_date('31/12/9999','dd/mm/yyyy'))
                                                            end NULLS LAST) as Numproto_next,
           min(case when next_date_mec >= trunc(sysdate) then next_date_mec end) as dte_mec_next
      from t_next
     group by id_modele
    Sinon tu dois pouvoir juste joindre les 2 requêtes que tu as créé.

  3. #3
    LEK
    LEK est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    715
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 715
    Par défaut
    Merci pour ton aide.
    J'ai fais des tests avec différents jeux de données et ça à l'air de coller.
    Je me replonge dans les tutos car je pense que je n'ai pas complètement saisi le fonctionnement : j'aurais jurer que dans ce cas à je devais passer par les fonctions last_value/first_value.

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

    Informations forums :
    Inscription : Août 2008
    Messages : 2 952
    Par défaut
    C'est pas vraiment un problème de premier/dernier mais plutôt un problème de suivant donc LEAD.
    Après j'utilise aussi FIRST mais dans sa version agrégée.

  5. #5
    LEK
    LEK est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    715
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 715
    Par défaut
    Ok j'ai compris : merci!

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

Discussions similaires

  1. Comportement fonctions imbriquées avec appel à Xmlhttprequest
    Par eirmag dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 04/05/2006, 16h10
  2. [Fonctions analytiques] : inhibe les indexs ?
    Par PpPool dans le forum Oracle
    Réponses: 18
    Dernier message: 20/04/2006, 18h22
  3. Réponses: 3
    Dernier message: 24/11/2005, 12h19
  4. Réponses: 7
    Dernier message: 21/11/2005, 14h21
  5. Réponses: 4
    Dernier message: 18/08/2005, 16h11

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