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 :
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 -- 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 ;
J'ai aussi un peu peur pour les performances, donc si vous avez de meilleures idées, je suis preneur !!
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;
Partager