Bonjour à tous,

J'ai une requête de ce type qui me sert de curseur :

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
 
select produit, jour, valeur
from
(
  select produit, jour, sum(ventes) valeur
  from tabledesventes
  where jour between sysdate - 28 and sysdate
  group by produit, jour
) t1
where valeur < (
  select avg(valeur)
  from (
    select sum(ventes) valeur
    from tabledesventes
    where produit = t1.produit
    and jour between sysdate - 28 and sysdate
  )
) * 5
or 1 > (
  select avg(valeur)
  from (
    select sum(ventes) valeur
    from tabledesventes
    where produit = t1.produit
    and jour between sysdate - 28 and sysdate
  )
)
On voit clairement que j'ai deux fois exactement la même sous-requête sur tabledesventes (dans la clause where).

Et une troisième fois similaire dans la clause from.

D'un point de vue performances, Oracle a l'air de retrouver ses petits.

Mais d'un point de vue lisibilité (car vous vous en doutez, j'ai fais la version courte...) c'est pas terrible.

J'ai été tenté de créer une vue :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
 
select produit, jour, sum(ventes) valeur
from tabledesventes
where jour between sysdate - 28 and sysdate
group by produit, jour
Mais je préfère éviter, dans la mesure où je voudrais éviter d'avoir 3 ou 4 vues par procédure stockées... (et dans ce cas, pourquoi ne pas faire aussi une vue pour la requête entière).

Je me demande alors quelles autres solutions s'offrent à mois...

Je suis tenté par le "with", mais est-ce que ça marche pour un curseur ?

Je pense à un truc du genre :

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
 
cursor c is
with ventes_28_jours as (
  select produit, jour, sum(ventes) valeur
  from tabledesventes
  where jour between sysdate - 28 and sysdate
  group by produit, jour
),
moyene_28_jour as (
  select produit, avg(valeur) valeur
  from ventes_28_jours
  group by produit
)
select v1.produit, v1.jour, v1.valeur
from ventes_28_jours v1
where v1.valeur < (
  select v2.valeur
  from moyenne_28_jours v2
  where v2.produit = v1.produit
) * 5
or 1 > (
  select v2.valeur
  from moyenne_28_jours v2
  where v2.produit = v1.produit
)
Est-ce qu'il existe d'autres astuces du genre qui permettent de réduire le code (et améliorer les perfs) ?