Bonjour,
J'ai un besoin un peu particulier que je n'arrive pas à traiter sans requête récursive.
J'ai peut être loupé un truc ceci étant dit ...
J'ai donc une table avec 3 dimenssions :
- id_per : l'identifiant d'une personne
- dtDeb : date de début de plage
- dtFin : date de fin de plage.
Dans cette table est loggé l'id d'une personne avec la plage sur laquelle il a travaillé.
On peut remarquer que : dtDeb < dtFin pour une même ligne.
En plus de ceci on a une contrainte fonctionnelle qui spécifie que 2 plages de deux lignes distinct ne peuvent pas se chevaucher.
Le but étant de regrouper les différentes plages selon la personne qui travaille tout en faisant une rupture par différente personne / plage continue de travaille.
Un exemple :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 donnée en entrée : idcon dtDeb dtFin ----------------------------- with tmp as ( select 2, trunc(current_date - interval '10' day), trunc(current_date - interval '9' day) from dual union all select 2, trunc(current_date - interval '7' day), trunc(current_date - interval '6' day) from dual union all select 3, trunc(current_date - interval '5' day), trunc(current_date - interval '3' day) from dual union all select 2, trunc(current_date - interval '2' day), trunc(current_date) from dual union all select 2, trunc(current_date + interval '2' day), trunc(current_date + interval '4' day) from dual ) select * from tmp;
Sortie voulue :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 idcon dtDeb dtFin ------------------------------------- 2 2013-02-23 2013-02-27 3 2013-02-28 2013-03-02 2 2013-03-03 2013-03-09
Ma requête actuelle :
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 with tmp as ( select idcon, dtdeb, dtfin, row_number() over(order by dtdeb) as rnk from tt), rec (idcon, dtdeb, dtfin, rnk, lvl) as ( select idcon, dtdeb, dtfin, rnk, 0 as lvl from tmp where rnk = 1 union all select b.idcon, b.dtdeb, b.dtfin, b.rnk, case when a.idcon = b.idcon then a.lvl else a.lvl + 1 end from rec a inner join tmp b on a.rnk + 1 = b.rnk) select max(idcon), min(dtdeb), max(dtfin), lvl from rec group by lvl
Y a-t-il une transformation possible de ceci pour que celà tourne sur une 10g ?
J'ai essayé un peu avec les fonctions de fenêtrages mais n'y suis pas arrivé.
Merci.
Partager