Dit is een beetje ingewikkeld. In plaats van rank()
. te gebruiken of iets dergelijks, gebruik lag()
om te zien wanneer er iets verandert. Voer vervolgens een cumulatieve som van de vlag uit.
select dept, date1,
CASE WHEN StartFlag = 0 THEN 1
ELSE 1+StartFlag+NVL(lag(StartFlag) over (order by date1),0)
END as rnk
from (select t1.*,
(case when dept = lag(dept) over (order by date1)
then 1
else 0
end) as StartFlag
from t1
) t1
order by date1;
Hier is de SQLFiddle.
BEWERKEN:
Dit is Gordon die mijn eigen antwoord bewerkt. Oeps. De oorspronkelijke zoekopdracht was 90% van de weg daarheen. Het identificeerde de groepen waar de nummers zouden moeten toenemen, maar hebben de nummers niet toegewezen binnen de groepen. Ik zou dit doen met een ander niveau van row_number()
zoals in:
select dept, date1,
row_number() over (partition by dept, grp order by date1) as rnk
from (select dept, date1, startflag,
sum(StartFlag) over (partition by dept order by date1) as grp
from (select t1.*,
(case when dept = lag(dept) over (order by date1)
then 0
else 1
end) as StartFlag
from t1
) t1
) t1
order by date1;
Het algemene idee is dus het volgende. Gebruik eerst lag()
om te bepalen waar een groep begint (dat wil zeggen, waar er van de ene datum naar de andere een afdelingswisseling is). Wijs hier vervolgens een "groeps-ID" aan toe door een cumulatieve som uit te voeren. Dit zijn de records die moeten worden opgesomd. De laatste stap is om ze op te sommen met behulp van row_number()
.