不是一個真正的問題的答案,但太大評論...
試圖保持在一個父表捲起數據通常不是一個好主意,因爲它容易出錯和混亂。例如,在這種情況下,您想要將leaves
中的值添加到leaveentitle
中的_used
值,這表明_used
值不爲零,這反過來表明您打算多次運行它。但這意味着您可以不止一次地計數相同的leaves
數據。如果我添加的數據是這樣的:
insert into leaveentitle(app_no, ecn, cl_entitled, sl_entitled, lta_entitled)
values (1, 1234, 5, 10, 5);
insert into leaves (app_no, ecn, from_date, to_date, app_date,
no_of_days, leave_type, status)
values (1, 1234, date '2012-01-01', date '2012-01-02', date '2011-12-15',
2, 'SL', 'APPROVED');
...,然後運行類似於@Szilard巴拉尼的(與nvl()
和sum()
)我最終的更新:
select app_no, ecn, sl_entitled, sl_used, sl_unused
from leaveentitle where app_no = 1 and ecn = 1234;
APP_NO ECN SL_ENTITLED SL_USED SL_UNUSED
------ ------ ----------- ------- ---------
1 1234 10 2
...看起來好;但當時如果我再添leaves
記錄:
insert into leaves (app_no, ecn, from_date, to_date, app_date,
no_of_days, leave_type, status)
values (1, 1234, date '2012-02-01', date '2012-02-01', date '2012-01-15',
1, 'SL', 'BOOKED');
...並再次更新,我得到:
select app_no, ecn, sl_entitled, sl_used, sl_unused
from leaveentitle where app_no = 1 and ecn = 1234;
APP_NO ECN SL_ENTITLED SL_USED SL_UNUSED
------ ------ ----------- ------- ---------
1 1234 10 5
...這顯然是錯誤的,因爲我只用了3天,不5.(我感覺我的公司做了這樣的事情,因爲我的休假餘額很少準確)。您可以重新計算更新中的所有內容,而不是添加到現有值;或者你可以嘗試使用觸發器來更新總數;或者您可以嘗試維護狀態,以便知道哪些leaves
記錄已包含在內。但最後兩個選項也變得很糟糕,尤其是當現有記錄發生變化時。
一個更簡單的方法是從leaveentitle
刪除_used
和_unused
列,並根據需要生成的值,可能是通過一個視圖,使生活更容易爲你的用戶,使用查詢像(猜的連接條件既app_no
和ecn
,但這個問題並不清楚):
select le.app_no, le.ecn, le.sl_entitled,
sum(case when l.leave_type = 'SL' then l.no_of_days else 0 end) as sl_used
from leaveentitle le
join leaves l on l.app_no = le.app_no and l.ecn = le.ecn
group by le.app_no, le.ecn, le.sl_entitled;
APP_NO ECN SL_ENTITLED SL_USED
------ ------ ----------- -------
1 1234 10 3
...或者把所有的值形成的原父表:
create or replace view leaveview as
select le.app_no, le.ecn,
le.sl_entitled, ls.sl_used, le.sl_entitled - ls.sl_used as sl_unused,
le.cl_entitled, ls.cl_used, le.cl_entitled - ls.cl_used as cl_unused,
le.lta_entitled, ls.lta_used, le.lta_entitled - ls.lta_used as lta_unused
from leaveentitle le
left join (select l.app_no, l.ecn,
sum(case when l.leave_type = 'SL' then l.no_of_days else 0 end) as sl_used,
sum(case when l.leave_type = 'CL' then l.no_of_days else 0 end) as cl_used,
sum(case when l.leave_type = 'LTA' then l.no_of_days else 0 end) as lta_used
from leaves l
group by l.app_no, l.ecn
) ls on ls.app_no = le.app_no and ls.ecn = le.ecn;
select * from leaveview where app_no = 1 and ecn = 1234;
APP_NO ECN SL_ENTITLED SL_USED SL_UNUSED CL_ENTITLED CL_USED CL_UNUSED LTA_ENTITLED LTA_USED LTA_UNUSED
------ ------ ----------- ------- --------- ----------- ------- --------- ------------ -------- ----------
1 1234 10 3 7 5 0 5 5 0 5
這也使您可以輕鬆地,僅通過將其添加到視圖,而不是增加額外的派生值,如基於status
分裂的能力不得不添加另一個複雜的計算層並在某處更新。
什麼是app_no?申請人編號? – 2012-02-20 07:51:55