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 :

[Oracle9i SQL] Requêtes imbriquées avec fonction analytique


Sujet :

SQL Oracle

  1. #1
    Scorpi0
    Invité(e)
    Par défaut [Oracle9i SQL] Requêtes imbriquées avec fonction analytique
    Bonjour,

    J'ai réussi à faire une requête qui me renvoi ce que je veux, mais je la trouve tellement laide que j'aimerais savoir si on pouvait mieux faire.

    J'ai donc une table à deux champs : une date et une valeur; exemple :

    DATE || VALEUR
    01/10/2003 || 6,000000
    01/06/2006 || 7,000000
    01/07/2006 || 9,000000
    01/10/2007 || 8,000000

    J'aimerais, pour une date donnée, récupérer la valeur directement supérieur, et la valeur directement inférieur.

    Exemple : pour date = 15/06/2006, j'aimerais récupérer 7 et 9.
    Tout ça pour ensuite faire une interpolation toute simple (pour le 15/06/2006, la valeur vaudra donc 8). A priori, ca n'a pas l'air compliqué.

    Voici ma requête ignoble avec 4 select imbriqués et 3 fonctions analytiques :

    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
    -- Selection du premier enregistrement et calcul d'interpolation
    select dt, val_dt, veille, val_veille, val_dt, to_date('06/09/2005','DD/MM/YYYY') as interpol, val_dt - ((val_dt - val_veille)/(dt - veille)) * dt as val_interpol
    from
    (
      -- Selection uniquement des differences superieur à 0, ordonne par difference croissante
      select t.*, dense_rank() over(order by dt asc) as myRANK
      from
      (
        -- Selection de valeurs courante avec les valeurs de la veille
        select dt,
               val as val_dt,
               lag(dt, 1) over(order by dt) veille,
               lag(val, 1) over(order by dt) val_veille
        from
        (
          --  Selection des difference de dates d'apres la date en parametre ordonne par date
          select t.date_val - to_date('06/09/2005','DD/MM/YYYY') as DT, 
                 t.val as VAL
          from table_test t
          order by dt asc
        )
      ) t
      where t.dt > 0 
    )
    where myRANK = 1
    ;
    Le code pour générer la table d'exemple :

    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
    34
    35
    36
    37
    38
    39
    40
    41
    create table TABLE_TEST
    (
      DATE_VAL DATE,
      VAL      NUMBER(21,6) not null
    )
    ;
    insert into TABLE_TEST (DATE_VAL, VAL)
    values (to_date('01-05-2003', 'dd-mm-yyyy'), 1);
    insert into TABLE_TEST (DATE_VAL, VAL)
    values (to_date('01-06-2003', 'dd-mm-yyyy'), 2);
    insert into TABLE_TEST (DATE_VAL, VAL)
    values (to_date('01-07-2003', 'dd-mm-yyyy'), 3);
    insert into TABLE_TEST (DATE_VAL, VAL)
    values (to_date('01-08-2003', 'dd-mm-yyyy'), 4);
    insert into TABLE_TEST (DATE_VAL, VAL)
    values (to_date('01-09-2003', 'dd-mm-yyyy'), 5);
    insert into TABLE_TEST (DATE_VAL, VAL)
    values (to_date('01-10-2003', 'dd-mm-yyyy'), 6);
    insert into TABLE_TEST (DATE_VAL, VAL)
    values (to_date('01-06-2006', 'dd-mm-yyyy'), 7);
    insert into TABLE_TEST (DATE_VAL, VAL)
    values (to_date('01-10-2007', 'dd-mm-yyyy'), 8);
    insert into TABLE_TEST (DATE_VAL, VAL)
    values (to_date('01-07-2006', 'dd-mm-yyyy'), 9);
    insert into TABLE_TEST (DATE_VAL, VAL)
    values (to_date('01-09-2006', 'dd-mm-yyyy'), 10);
    insert into TABLE_TEST (DATE_VAL, VAL)
    values (to_date('01-10-2006', 'dd-mm-yyyy'), 11);
    insert into TABLE_TEST (DATE_VAL, VAL)
    values (to_date('01-11-2006', 'dd-mm-yyyy'), 12);
    insert into TABLE_TEST (DATE_VAL, VAL)
    values (to_date('01-02-2007', 'dd-mm-yyyy'), 13);
    insert into TABLE_TEST (DATE_VAL, VAL)
    values (to_date('01-05-2007', 'dd-mm-yyyy'), 14);
    insert into TABLE_TEST (DATE_VAL, VAL)
    values (to_date('01-06-2007', 'dd-mm-yyyy'), 15);
    insert into TABLE_TEST (DATE_VAL, VAL)
    values (to_date('01-09-2007', 'dd-mm-yyyy'), 16);
    insert into TABLE_TEST (DATE_VAL, VAL)
    values (to_date('01-11-2007', 'dd-mm-yyyy'), 17);
    commit;
    J'ai aussi un peu peur pour les performances, donc si vous avez de meilleures idées, je suis preneur !!
    Dernière modification par Scorpi0 ; 04/07/2008 à 16h35.

  2. #2
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    Select dat_deb, dat_fin, val_deb, val_fin
      From 
      (Select date_val dat_deb, lead(date_val) over(order by date_val) dat_fin, 
              val val_deb, lead(val) over(order by date_val) val_fin
        From table_test t
      )  
    Where dat_deb <= to_date('15/06/2006','DD/MM/YYYY') 
      And dat_fin >= to_date('15/06/2006','DD/MM/YYYY') 
    /
    DAT_DEB  DAT_FIN     VAL_DEB    VAL_FIN
    -------- -------- ---------- ----------
    01/06/06 01/07/06          7          9
    Je me demande bien c'est quoi la fonction d'interpolation à 2 points

  3. #3
    Scorpi0
    Invité(e)
    Par défaut
    Raaaah merci beaucoup
    Je savais bien que y'avait 3 fois plus simple

    Au final ca donne un truc de ce gout la :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT dat_deb, dat_fin, val_deb, val_fin,
    val_fin - (
            (val_fin - val_deb)      /        (
              (dat_fin - to_date('15/06/2006','DD/MM/YYYY')) - (dat_deb - to_date('15/06/2006','DD/MM/YYYY'))
            )
    ) * (dat_fin - to_date('15/06/2006','DD/MM/YYYY')) as val_interpol
      FROM 
      (SELECT date_val dat_deb, lead(date_val) over(ORDER BY date_val) dat_fin, 
              val val_deb, lead(val) over(ORDER BY date_val) val_fin
        FROM table_test t
      )  
    WHERE dat_deb <= to_date('15/06/2006','DD/MM/YYYY') 
      AND dat_fin >= to_date('15/06/2006','DD/MM/YYYY')

  4. #4
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    OK ! C'est bien une interpolation, tant pis pour moi.

Discussions similaires

  1. [MySQL] Erreur SQL 1064 : Requête imbriquée avec jointure !
    Par patchankito dans le forum Langage SQL
    Réponses: 5
    Dernier message: 31/01/2006, 10h37
  2. Réponses: 7
    Dernier message: 21/11/2005, 14h21
  3. [SQL] Requête complexe avec appel multiple à la même table
    Par Julien Dufour dans le forum Langage SQL
    Réponses: 9
    Dernier message: 14/04/2005, 14h12
  4. [PL/SQL]requête imbriquée
    Par Nadine dans le forum Oracle
    Réponses: 6
    Dernier message: 01/02/2005, 16h21
  5. [Requête] Problème avec fonction "DATE_FORMAT()"
    Par sekiryou dans le forum Requêtes
    Réponses: 4
    Dernier message: 11/01/2005, 21h52

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