Похоже, вам нужно это:
select
m
,max(p)keep(dense_rank first order by decode(p,null,null,serial) desc nulls last) max_p
,max(q)keep(dense_rank first order by decode(q,null,null,serial) desc nulls last) max_q
,max(p)keep(dense_rank first order by decode(p,null,null,serial) desc nulls last)
/
max(q)keep(dense_rank first order by decode(q,null,null,serial) desc nulls last)
as result
from mytable
group by m;
M MAX_P MAX_Q RESULT
-- ---------- ---------- ----------
m1 12 6 2
m2 20 4 5
Полный пример:
with mytable(serial,m,p,q) as (
select 1, 'm1', 10, null from dual
union
select 2, 'm1', 12, null from dual
union
select 3, 'm1', null, 5 from dual
union
select 4, 'm2', 20 , null from dual
union
select 5, 'm1', null, 6 from dual
union
select 6, 'm2', null, 4 from dual
)
select
m
,max(p)keep(dense_rank first order by decode(p,null,null,serial) desc nulls last) max_p
,max(q)keep(dense_rank first order by decode(q,null,null,serial) desc nulls last) max_q
,max(p)keep(dense_rank first order by decode(p,null,null,serial) desc nulls last)
/
max(q)keep(dense_rank first order by decode(q,null,null,serial) desc nulls last)
as result
from mytable
group by m;