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

Mode arborescent

Message précédent Message précédent   Message suivant Message suivant
  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.

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