Вы можете использовать connect by level
выражений, соединяющихся с вашей таблицей с помощью Conditional Aggregation
:
with tab_age as
(
select min(level-1) as age1, max(level-1) as age2
from dual
connect by level <= 20
group by floor((level-1)/5)
), tab(age,year,score) as
(
select 0 , 2018, 10 from dual union all
select 7 , 2019, 20 from dual union all
select 11, 2018, 30 from dual union all
select 13, 2019, 40 from dual union all
select 14, 2018, 50 from dual
), tab2 as
(
select t2.age1, t2.age2,
count( case when t1.year=2018 then 1 end ) as "2018",
count( case when t1.year=2019 then 1 end ) as "2019"
from tab t1
right join tab_age t2 on t1.age between t2.age1 and t2.age2
group by t2.age1, t2.age2
order by t2.age1, t2.age2
)
select concat(concat(age1,'-'),age2) as age,
"2018", "2019"
from tab2;
AGE 2018 2019
0-4 1 0
5-9 0 1
10-14 2 1
15-19 0 0
и
with tab_age as
(
select min(level-1) as age1, max(level-1) as age2
from dual
connect by level <= 20
group by floor((level-1)/5)
), tab(age,year,score) as
(
select 0 , 2018, 10 from dual union all
select 7 , 2019, 20 from dual union all
select 11, 2018, 30 from dual union all
select 13, 2019, 40 from dual union all
select 14, 2018, 50 from dual
), tab2 as
(
select t2.age1, t2.age2,
sum( case when t1.year=2018 then score else 0 end ) as "2018",
sum( case when t1.year=2019 then score else 0 end ) as "2019"
from tab t1
right join tab_age t2 on t1.age between t2.age1 and t2.age2
group by t2.age1, t2.age2
order by t2.age1, t2.age2
)
select concat(concat(age1,'-'),age2) as age,
"2018", "2019"
from tab2;
AGE 2018 2019
0-4 10 0
5-9 0 20
10-14 80 40
15-19 0 0
Демо