I have a query containing 0
or 1
in a column. For demonstration purposes I replaced the 1
with 77
so its more easy to see:
select dates.d the_date
, case TO_CHAR(dates.d, 'd') when '7' then 0 when '1' then 0
else 77
end as is_workday
from (SELECT (to_date('01.01.2019','dd.mm.yyyy') + (LEVEL -1))
AS d FROM DUAL connect by level <=(
to_date('31.12.2020','dd.mm.yyyy')-(to_date('01.01.2019','dd.mm.yyyy')))
) as dates
The result is simply a consecutive date column and a marker if this date is a workday or not. (in real life I do a holiday calculation as well, but that's not the problem):
| THE_DATE | IS_WORKDAY |
| 2019-01-01 00:00:00 | 77 |
| 2019-01-02 00:00:00 | 77 |
| 2019-01-03 00:00:00 | 77 |
| 2019-01-04 00:00:00 | 77 |
| 2019-01-05 00:00:00 | 0 |
| 2019-01-06 00:00:00 | 0 |
| 2019-01-07 00:00:00 | 77 |
| 2019-01-08 00:00:00 | 77 |
| 2019-01-09 00:00:00 | 77 |
| 2019-01-10 00:00:00 | 77 |
....
I want to add a running total over is_workday
, meaning a cumulative value. I am sure Oracles window functions are made for this.
SELECT x.the_date
, x.is_workday
, sum(x.is_workday) over (
partition by x.the_date -- define the window
order by x.the_date asc -- order inside window
rows between unbounded preceding -- sum to top
and current row -- sum ending here
) as workdays_cumul
FROM (
select dates.d the_date
, case TO_CHAR(dates.d, 'd') when '7' then 0 when '1' then 0
else 77
end as is_workday
from (SELECT (to_date('01.01.2019','dd.mm.yyyy') + (LEVEL -1))
AS d FROM DUAL connect by level <=(
to_date('31.12.2020','dd.mm.yyyy')-(to_date('01.01.2019','dd.mm.yyyy')))
) as dates
) x
order by x.the_date
;
But I must miss something here, because I do not get a running total, but just the value itself.
| THE_DATE | IS_WORKDAY | WORKDAYS_CUMUL |
| 2019-01-01 00:00:00 | 77 | 77 |
| 2019-01-02 00:00:00 | 77 | 77 |
| 2019-01-03 00:00:00 | 77 | 77 |
| 2019-01-04 00:00:00 | 77 | 77 |
| 2019-01-05 00:00:00 | 0 | 0 |
| 2019-01-06 00:00:00 | 0 | 0 |
| 2019-01-07 00:00:00 | 77 | 77 |
| 2019-01-08 00:00:00 | 77 | 77 |
....
Obviously it should be:
| THE_DATE | IS_WORKDAY | WORKDAYS_CUMUL |
| 2019-01-01 00:00:00 | 77 | 77 |
| 2019-01-02 00:00:00 | 77 | 154 |
| 2019-01-03 00:00:00 | 77 | 231 |
...
I thought it would wirk like this:
sum(x.is_workday)
-- do the sum over the77
-valuespartition by x.the_date
-- make windows/sections/parts with one row each (in my case)order by x.the_date asc
-- order those rows by daterows between unbounded preceding
-- sum between very first row...and current row
-- ... and the current row.
What am I missing here?