You could use a CTE to get a table with a sequence of numbers up to the highest rank in your table, and then join with that:
with nums as (
select
level-1 lvl
from dual
connect by
level-1 < = (select max(rang) from foo)
)
select
foo.event_date + nums.lvl
, rang
from foo
join nums
on nums.lvl <= foo.rang
order by
foo.event_date + nums.lvl;
Use grouping sets. You can try it here.
select cat1, cat2, cat3, sum(val) as val
from t1 join t2 on t1.f_id = t2.f_id
group by grouping sets ((cat1),(cat1, cat2),(cat1, cat2, cat3))
order by cat1, cat2 nulls first, cat3 nulls first
OUTPUT
cat1 cat2 cat3 val
A 15
A a 10
A a aa 4
A a ab 6
A b 5
A b ba 4
A b bb 1
B 21
B c 12
B c ca 6
B c cb 6
B d 9
B d da 9
If you prefer underscore than null
use NVL
select cat1, nvl(cat2,'_') as cat2, nvl(cat3, '_') as cat3, sum(val)
from t1 join t2 on t1.f_id = t2.f_id
group by grouping sets ((cat1),(cat1, cat2),(cat1, cat2, cat3))
order by cat1, cat2 nulls first, cat3 nulls first
Best Answer
If you are using Oracle 12c or higher, you can
CROSS APPLY
with aCONNECT BY LEVEL
query generating the numbers from 1 toVAL_COL
. Something like this (I don't have an instance ready and SQLFiddle uses 11g, which doesn't support this):If you are on 11g or higher, you can use
Recursive Refactored Subquery
.Prior to 11g, you would need to use a
pipeline function