Есть два относительно одинаковых запроса. Второй запрос выводит суммарные данные первого.
Нельзя ли как-то их оптимизировать и выполнять все в одном запросе? И выводить сумму в конце каждого столбца?
Основной запрос:
select round(hz,2) HZ,bz,round(h0,1)HO,naim,
round(sum(pf),2) PF,round(sum(pt),2) PT,
round(sum(pdm),2) PDM,round(sum(pdp),2) PDP,round(sum(pbm),2)PBM,round(sum(pbp),2) PBP,
round(sum(tp)/60,2) TP,round(sum(pf)/sum(tp)*60,1)SFP
from (select r.hz,r.bz,r.h0,m.naim,r.pf,r.pt,r.pdm,r.pdp,r.pbm ,r.pbp,
case when ((r.tz-p.ts)*1440 < 10) and ((r.i_rez3/60) < 10) then (case when r.n > 1 then ((r.ts-p.ts)*1440) else ((r.ts-r.tz)*1440) end)
when ((r.tz-p.ts)*1440 > 10) and ((r.i_rez3/60) < 10) then (case when r.n > 1 then (((r.ts-r.tz)*1440)+10) else((r.ts-r.tz)*1440)end)
when ((r.tz-p.ts)*1440 < 10) and ((r.i_rez3/60) > 10) then (case when r.n > 1 then ((((r.ts-p.ts)*1440)-(r.i_rez3/60-10)))else((((r.ts-r.tz)*1440)-(r.i_rez3/60-10))) end)
when ((r.tz-p.ts)*1440 > 10) and ((r.i_rez3/60) > 10) then (case when r.n > 1 then ((((r.ts-r.tz))*1440+10-(r.i_rez3/60-10))) else((((r.ts-r.tz))*1440-(r.i_rez3/60-10)))end) end as tp
from zxp.rulon r,zxp.mc m,zxp.rulon p
where
r.ts between to_date('14.04.16 22:00:00','dd.mm.yy hh24:mi:ss') and to_date('15.04.16 7:00:00','dd.mm.yy hh24:mi:ss')+1
and r.ms = m.ukey
and p.ts = (
select max(pp.ts)
from zxp.rulon pp
where pp.ts <= r.tz
and pp.ts > r.tz-1))
group by hz,h0,bz,naim
order by hz,h0,bz,naim
Дублирующий с суммой:
select 'Итого:',round(sum(pf),2)"Р физ.",round(sum(pt),2)"Р теор.",
round(sum(pdm),2)"Р доп. -",round(sum(pdp),2)"Р доп. +",round(sum(pbm),2)"Р бр. -",round(sum(pbp),2)"Р бр. +",
round(sum(tp)/60,2)"Длит.",round(sum(pf)/sum(tp)*60,1)"Произв."
from (select
r.pf,r.pt,r.pdm,r.pdp,r.pbm,r.pbp,
case when ((r.tz-p.ts)*1440 < 10) and ((r.i_rez3/60) < 10) then (case when r.n > 1 then ((r.ts-p.ts)*1440) else ((r.ts-r.tz)*1440) end)
when ((r.tz-p.ts)*1440 > 10) and ((r.i_rez3/60) < 10) then (case when r.n > 1 then (((r.ts-r.tz)*1440)+10) else((r.ts-r.tz)*1440)end)
when ((r.tz-p.ts)*1440 < 10) and ((r.i_rez3/60) > 10) then (case when r.n > 1 then ((((r.ts-p.ts)*1440)-(r.i_rez3/60-10)))else((((r.ts-r.tz)*1440)-(r.i_rez3/60-10))) end)
when ((r.tz-p.ts)*1440 > 10) and ((r.i_rez3/60) > 10) then (case when r.n > 1 then ((((r.ts-r.tz))*1440+10-(r.i_rez3/60-10))) else((((r.ts-r.tz))*1440-(r.i_rez3/60-10)))end) end as tp
from zxp.rulon r,zxp.rulon p
where r.ts between to_date('14.04.16 22:00:00','dd.mm.yy hh24:mi:ss') and to_date ('15.04.16 7:00:00','dd.mm.yy hh24:mi:ss') and
p.ts =(select max(pp.ts) from zxp.rulon pp where pp.ts <= r.tz and pp.ts > r.tz-1))
Ответ
Используйте функцию ROLLUP при группировке, она умеет подводить промежуточные итоги по указанным колонкам. Если нам нужен итог только по части колонок из group by, то оставшиеся следует заключить в дополнительные скобки. Т.к. вы хотите получить только общий итог - то все колонки надо заключить в дополнительные скобки в rollup. Примерно так:
select round(hz,2) HZ,bz,round(h0,1)HO,naim, .....
from ...
group by ROLLUP((hz,h0,bz,naim)) --<---- Колонки в двойных скобках для общего итога !!!
order by hz,h0,bz,naim
В итоговой записи все колонки указанные к группировке будут иметь значение NULL, что можно использовать для вывода надписей 'Итого' и т.п. Или используйте функцию grouping(колонка) которая вернет 1 - если данная строка итог или 0 - если это строка данных.
Комментариев нет:
Отправить комментарий