есть у меня вот такая процедура, я ток учусь SQL так мне вот интересно так как я сделал это нормально или так не делаться?
меня смущает что много временных таблиц и в итоговом select-e много join-ов получается или это нормально?
create proc general.usp_derevo_fin_po_ob
--исходные параметры
@mes_tek tinyint,
@god_tek smallint
as
begin
set nocount on
--вычисляемые параметры
declare @first_day_tm smalldatetime --первый день из @god_tek и @mes_tek
declare @last_day_tm smalldatetime --последний день из @god_tek и @mes_tek
declare @first_day_pm smalldatetime --первый день пред месяца
declare @last_day_pm smalldatetime --последний день пред месяца
declare @first_day_tg smalldatetime --первый день тек года
declare @mes_pred tinyint --пред месяц
declare @god_mes_pred smallint --год пред месяца
declare @mes_sled tinyint --след месяц
declare @god_mes_sled smallint --год след месяц
--зад знач парам
set @first_day_tm = prog.DateSerial(@god_tek, @mes_tek, 1)
set @last_day_tm = prog.DateSerial(@god_tek, @mes_tek + 1, 0)
set @first_day_pm = prog.DateSerial(@god_tek, @mes_tek - 1, 1)
set @last_day_pm = prog.DateSerial(@god_tek, @mes_tek , 0)
set @first_day_tg = prog.DateSerial(@god_tek, 1 , 1)
set @mes_pred = month(@first_day_pm)
set @god_mes_pred = year(@first_day_pm)
set @mes_sled = month(prog.DateSerial(@god_tek, @mes_tek + 1, 1))
set @god_mes_sled = year(prog.DateSerial(@god_tek, @mes_tek + 1, 1))
-- 2 - сальдо
declare @saldo table
(id_ob int null,
saldo decimal(15,3) null)
insert into @saldo( id_ob, saldo )
select id_ob, saldo
from pldo_fin.ob_saldo_ng
where god = @god_tek --текущий год
-- 3 - к оплате нарастающим
declare @k_opl_n table
(id_ob int null,
k_opl_nar decimal(15,3) null)
insert into @k_opl_n(id_ob, k_opl_nar)
select oo.id_ob, sum(vip.fakt_dc_okv - vip.vozvrat_vr)
from pldo_vip.object as ob
inner join pldo_vip.org_ob as oo
on ob.id_ob = oo.id_ob
inner join pldo_vip.plg_org as plg
on oo.id_org_ob = plg.id_org_ob and plg.god = @god_tek -- текущий год
inner join pldo_vip.vipoln as vip
on plg.id_plg = vip.id_plg and vip.kod_mes < @mes_tek -- текущий месяц
group by oo.id_ob
-- 4 - к оплате за месяц
declare @k_opl_tm table
(id_ob int null,
k_opl_tm decimal(15,3) null)
insert into @k_opl_tm(id_ob, k_opl_tm)
select oo.id_ob, sum(vip.fakt_dc_okv - vip.vozvrat_vr)
from pldo_vip.object as ob
inner join pldo_vip.org_ob as oo
on ob.id_ob = oo.id_ob
inner join pldo_vip.plg_org as plg
on oo.id_org_ob = plg.id_org_ob and plg.god = @god_mes_pred -- год зависит от месяца
inner join pldo_vip.vipoln as vip
on plg.id_plg = vip.id_plg and vip.kod_mes = @mes_pred -- предыдущий месяц
group by oo.id_ob
-- 5 - оплачено пред месяц
declare @opl_pred_mes table
(id_ob int null,
opl_pred_mes decimal(15,3) null);
insert into @opl_pred_mes(id_ob, opl_pred_mes)
select id_ob, sum(summa)
from buh.oborot_den_sr
where (kod_np = 1 and kod_t = 1 and data between @first_day_pm and @last_day_pm) or (kod_t = 2 and data between @first_day_pm and @last_day_pm) --оплачено за выполн работы
group by id_ob --первый день и последний день пред месяца
-- 6,7 - зачтено авансов пред месяц
declare @az_pred_mes table
(id_ob int null,
ta_z_pr_mes decimal(15,3) null,
ca_z_pr_mes decimal(15,3) null,
ind_pr_mes decimal(15,3) null)
insert into @az_pred_mes(id_ob, ta_z_pr_mes, ca_z_pr_mes, ind_pr_mes)
select id_ob, tek_av_z, cel_av_z, indeks
from pldo_fin.ob_avans_zachet
where god = @god_mes_pred and kod_mes = @mes_pred -- год зависит от месяца --предыдущий месяц
-- 8 - зачтено материалов пред месяц
declare @mz_pred_mes table
(id_ob int null,
mz_pred_mes decimal(15,3) null)
insert into @mz_pred_mes(id_ob, mz_pred_mes)
select id_ob, mat_dor_z + mat_bel_z + mat_pr_z
from pldo_fin.ob_mat_zachet
where god = @god_mes_pred and kod_mes = @mes_pred -- год зависит от месяца --предыдущий месяц
-- оплачено на начало месяца
declare @opl_na_nm table
(id_ob int null,
opl_na_nm decimal(15,3) null)
insert into @opl_na_nm(id_ob, opl_na_nm)
select id_ob, sum(summa)
from buh.oborot_den_sr
where (kod_np = 1 and kod_t = 1 and data between @first_day_tg and @last_day_pm) or (kod_t = 2 and data between @first_day_tg and @last_day_pm) --оплачено за выполн работы
group by id_ob --с начала года по последний день пред месяца
-- зачтено авансов на начало месяца
declare @az_na_nm table
(id_ob int null,
az_na_nm decimal(15,3) null)
insert into @az_na_nm(id_ob, az_na_nm)
select id_ob, sum(tek_av_z + cel_av_z + indeks)
from pldo_fin.ob_avans_zachet
where god = @god_tek and kod_mes < @mes_tek --тек год тек месяц
group by id_ob
-- зачтено материалов на начало месяца
declare @mz_na_nm table
(id_ob int null,
mz_na_nm decimal(15,3) null)
insert into @mz_na_nm(id_ob, mz_na_nm)
select id_ob, sum(mat_dor_z + mat_bel_z + mat_pr_z )
from pldo_fin.ob_mat_zachet
where god = @god_tek and kod_mes < @mes_tek --тек год тек месяц
group by id_ob
-- 10 - оплачено за тек месяц
declare @opl_tm table
(id_ob int null,
opl_tm decimal(15,3) null)
insert into @opl_tm(id_ob, opl_tm)
select id_ob, sum(summa)
from buh.oborot_den_sr
where (kod_np = 1 and kod_t = 1 and data between @first_day_tm and @last_day_tm) or (kod_t = 2 and data between @first_day_tm and @last_day_tm) --оплачено за выполн работы
group by id_ob --первый день тек месяца по посл день тек месяца
-- 13 - пост тек авансов на след мес
declare @tek table
(id_ob int null,
tek_av_post decimal(15,3) null)
insert into @tek(id_ob, tek_av_post)
select id_ob, sum(summa)
from buh.oborot_den_sr
where kod_np = 2 and god = @god_mes_sled and kod_mes = @mes_sled and kod_t = 1 -- след месяц, год от месяца
group by id_ob;
-- 15 - пост цел авансов в этом месяце
declare @cel table
(id_ob int null,
cel_av_post decimal(15,3) null)
insert into @cel(id_ob, cel_av_post)
select id_ob, sum(summa)
from buh.oborot_den_sr
where kod_np = 3 and kod_t = 1 and data between @first_day_tm and @last_day_tm --первый день тек месяца по посл день тек месяца
group by id_ob;
select nif.kod_if, nif.nazv_if, nz.nazv_org, ob.nazv_ob, nf.nazv_fil, saldo, k_opl_nar, k_opl_tm,
case isnull(opl_pred_mes,0) + isnull(ta_z_pr_mes,0) + isnull(ca_z_pr_mes,0) + isnull(ind_pr_mes,0) + isnull(mz_pred_mes,0)
when 0 then null
else isnull(opl_pred_mes,0) + isnull(ta_z_pr_mes,0) + isnull(ca_z_pr_mes,0) + isnull(ind_pr_mes,0) + isnull(mz_pred_mes,0)
end as 'itogo_opl_pred_mes',
ta_z_pr_mes, ca_z_pr_mes , mz_pred_mes,
case isnull(saldo,0) + isnull(k_opl_nar,0) - isnull(opl_na_nm,0) - isnull(az_na_nm,0) - isnull(mz_na_nm,0)
when 0 then null
else isnull(saldo,0) + isnull(k_opl_nar,0) - isnull(opl_na_nm,0) - isnull(az_na_nm,0) - isnull(mz_na_nm,0)
end as 'zad_na_nm',
opl_tm,
case isnull(saldo,0) + isnull(k_opl_nar,0) - isnull(opl_na_nm,0) - isnull(az_na_nm,0) - isnull(mz_na_nm,0) - isnull(opl_tm,0)
when 0 then null
else isnull(saldo,0) + isnull(k_opl_nar,0) - isnull(opl_na_nm,0) - isnull(az_na_nm,0) - isnull(mz_na_nm,0) - isnull(opl_tm,0)
end as 'zad_na_tek_d',
atp.tek_av_p as 'tek_av_plan', tek_av_post, aсp.cel_av_p as 'cel_av_plan', cel_av_post, prim
from pldo_vip.object as ob
inner join nw.n_if as nif
on ob.kod_if = nif.kod_if
inner join general.org as nz
on ob.id_zak = nz.id_org and nz.id_org > 1
inner join nw.n_fil as nf
on ob.kod_fil = nf.kod_fil
left join @saldo as saldo
on ob.id_ob = saldo.id_ob
left join @k_opl_n as k_opl_n
on ob.id_ob = k_opl_n.id_ob
left join @k_opl_tm as k_opl_tm
on ob.id_ob = k_opl_tm.id_ob
--пред мес
left join @opl_pred_mes as opl_pred_mes
on ob.id_ob = opl_pred_mes.id_ob
left join @az_pred_mes as az_pred_mes
on ob.id_ob = az_pred_mes.id_ob
left join @mz_pred_mes as mz_pred_mes
on ob.id_ob = mz_pred_mes.id_ob
--нар
left join @opl_na_nm as opl_na_nm
on ob.id_ob = opl_na_nm.id_ob
left join @az_na_nm as az_na_nm
on ob.id_ob = az_na_nm.id_ob
left join @mz_na_nm as mz_na_nm
on ob.id_ob = mz_na_nm.id_ob
--tm
left join @opl_tm as opl_tm
on ob.id_ob = opl_tm.id_ob
--plan av
left join pldo_fin.ob_avans_plan as atp
on ob.id_ob = atp.id_ob and atp.god = 2009 and atp.kod_mes = 2 --год от месяца след мес
left join pldo_fin.ob_avans_plan as aсp
on ob.id_ob = aсp.id_ob and aсp.god = 2009 and aсp.kod_mes = 1 --тек год тек месяц
left join @tek as tek
on ob.id_ob = tek.id_ob
left join @cel as cel
on ob.id_ob = cel.id_ob
--prim
left join pldo_fin.prim_fin as pr
on ob.id_ob = pr.id_ob
--where задолженность на начало мес не равна 0, или поступившие/планируемые авансы не равны 0
where (ob.id_ob <> 1 and ob.kod_if <> 200 and (isnull(saldo,0) + isnull(k_opl_nar,0) - isnull(opl_na_nm,0) - isnull(az_na_nm,0) - isnull(mz_na_nm,0)) <> 0)
or (ob.id_ob <> 1 and ob.kod_if <> 200 and atp.tek_av_p <> 0)
or (ob.id_ob <> 1 and ob.kod_if <> 200 and tek_av_post <> 0)
or (ob.id_ob <> 1 and ob.kod_if <> 200 and aсp.cel_av_p <> 0)
or (ob.id_ob <> 1 and ob.kod_if <> 200 and cel_av_post <> 0)
order by kod_if, nazv_org, nazv_ob
end;
зы Microsoft SQL Server 2005 - 9.00.3239.00 (Intel X86) Apr 9 2008 22:56:02
сервер - Intel Xeon 5420 два штуки, 8 гб ОЗУ, HDD(10 шт) - raid1 - OS+MsSql-сервер, raid1 - всяка ерунда, raid50 + данные и логи БД