==============================實(shí)踐后===============================
如果兩個(gè)字段都是DATE型,那么直接用END_DATE - BEGIN_DATE即可,不需要任何轉(zhuǎn)型,取整直接用TRUNC即可:TRUNC(END_DATE - BEGIN_DATE),這樣是直接將小數(shù)部分舍去。
=====================================================================
*************實(shí)例(包括MONTHS_BETWEEN,ADD_MONTHS,MOD,LAST_DAY的用法)******************
/*
解決方案;本例假設(shè)用戶(hù)統(tǒng)計(jì)2007-05月份的報(bào)告及時(shí)率
1.需要要取得2007-05月份需要做隨訪(fǎng)的嬰兒信息
2.再查詢(xún)出這些嬰兒中在本次隨訪(fǎng)中已經(jīng)做了隨訪(fǎng)并且滿(mǎn)足<=20天的
*/
/*2007-5月需要隨訪(fǎng)的嬰兒ID*/
select T.ID,T.* /*不太準(zhǔn)確*/
from fy_new_baby t
where
mod(trunc(months_between(TO_DATE('2007-05-31', 'yyyy-mm-dd') ,t.birthday)),12) in (1,3,6,9,12)
and t.live = '1'
select T.ID,T.* /*比較準(zhǔn)確*/
FROM FY_NEW_BABY T
WHERE MOD(TRUNC(MONTHS_BETWEEN(TO_DATE('2007-05-31','yyyy-mm-dd'),T.BIRTHDAY)),12) IN (1,3,6,9,12)
AND T.LIVE = '1'
/*本月需要做隨訪(fǎng)的并且已經(jīng)做了隨訪(fǎng)的記錄
(其中也包括了以前做過(guò)隨訪(fǎng)而并非算是本次隨訪(fǎng)的,后面通過(guò)(隨訪(fǎng)日期-本次應(yīng)該隨訪(fǎng)日期)>0來(lái)將其排除掉*/
select v.* from fy_register_visit v
where v.new_baby_id in (select T.ID
from fy_new_baby t
where
mod(trunc(months_between(TO_DATE('2007-05-31', 'yyyy-mm-dd') ,t.birthday)),12) in (1,3,6,9,12)
and t.live = '1')
/*出生日期和本月的月差*/
SELECT MONTHS_BETWEEN(TO_DATE('2007-05-31','YYYY-MM-DD'),T.BIRTHDAY) FROM FY_NEW_BABY T
/*本月需要做隨訪(fǎng)的嬰兒在本月應(yīng)該隨訪(fǎng)的日期*/
select T.ID,T.BIRTHDAY,ADD_MONTHS(T.BIRTHDAY,TRUNC(MONTHS_BETWEEN(TO_DATE('2007-05-31','YYYY-MM-DD'),T.BIRTHDAY)) ),t.*
from fy_new_baby t WHERE T.ID IN (select T.ID
from fy_new_baby t
where
mod(trunc(months_between(TO_DATE('2007-05-31', 'yyyy-mm-dd') ,t.birthday)),12) in (1,3,6,9,12)
and t.live = '1')
/*需要在本月做隨訪(fǎng)的嬰兒的隨訪(fǎng)日期-本月應(yīng)該做隨訪(fǎng)的日期*/
select ff.id,v.vst_date,ff.birthday, ff.shouldvisit,(v.vst_date-ff.shouldvisit) as day from fy_register_visit v,
( select T.ID as id,T.BIRTHDAY as birthday,ADD_MONTHS(T.BIRTHDAY,TRUNC(MONTHS_BETWEEN(TO_DATE('2007-05-31','YYYY-MM-DD'),T.BIRTHDAY)) ) as shouldvisit
from fy_new_baby t WHERE T.ID IN (select T.ID
from fy_new_baby t
where
mod(trunc(months_between(TO_DATE('2007-05-31', 'yyyy-mm-dd') ,t.birthday)),12) in (1,3,6,9,12)
and t.live = '1') ) ff
where v.new_baby_id = ff.id
/*隨訪(fǎng)表中滿(mǎn)足(隨訪(fǎng)日期-本月應(yīng)該隨訪(fǎng)日期<=20)的*/
select ff.id,v.vst_date,v.vst_zonecode,ff.birthday, ff.shouldvisit,(v.vst_date-ff.shouldvisit) as day from fy_register_visit v,
( select T.ID as id,T.BIRTHDAY as birthday,ADD_MONTHS(T.BIRTHDAY,TRUNC(MONTHS_BETWEEN(TO_DATE('2007-05-31','YYYY-MM-DD'),T.BIRTHDAY)) ) as shouldvisit
from fy_new_baby t WHERE T.ID IN (select T.ID
from fy_new_baby t
where
mod(trunc(months_between(TO_DATE('2007-05-31', 'yyyy-mm-dd') ,t.birthday)),12) in (1,3,6,9,12)
and t.live = '1') ) ff
where v.new_baby_id = ff.id
and v.vst_date-ff.shouldvisit<=20
and v.vst_date-ff.shouldvisit>=0
/*2007-05月份需要隨訪(fǎng)的活產(chǎn)嬰兒總數(shù)---按地區(qū)分組
因?yàn)镕Y_NEW_BABY表中沒(méi)有地區(qū)字段,所以需要關(guān)聯(lián)FY_PREGNANT_REG表*/
select B.REP_ZONECODE , count(*) as shouldVisitNum
FROM FY_NEW_BABY T,FY_PREGNANT_REG B
WHERE MOD(TRUNC(MONTHS_BETWEEN(TO_DATE('2007-05-31','yyyy-mm-dd'),T.BIRTHDAY)),12) IN (1,3,6,9,12)
AND T.LIVE = '1'
AND T.CARD_ID = B.ID
GROUP BY B.REP_ZONECODE
/*2007-05月份需要隨訪(fǎng)的嬰兒并且已經(jīng)存在在隨訪(fǎng)表中并滿(mǎn)足(0=<隨訪(fǎng)日期-本月應(yīng)該隨訪(fǎng)日期<=20)的*/
select v.vst_zonecode, count(distinct v.id) as visitNum /*ff.id,v.vst_date,ff.birthday, ff.shouldvisit,(v.vst_date-ff.shouldvisit) as day*/
from fy_register_visit v,
(select T.ID as id,
T.BIRTHDAY as birthday,
ADD_MONTHS(T.BIRTHDAY,
TRUNC(MONTHS_BETWEEN(TO_DATE('2007-05-31',
'YYYY-MM-DD'),
T.BIRTHDAY))) as shouldvisit
from fy_new_baby t
WHERE T.ID IN (select T.ID
from fy_new_baby t
where mod(trunc(months_between(TO_DATE('2007-05-31',
'yyyy-mm-dd'),
t.birthday)),
12) in (1, 3, 6, 9, 12)
and t.live = '1')) ff
where v.new_baby_id = ff.id
and v.vst_date - ff.shouldvisit <= 20
and v.vst_date - ff.shouldvisit >= 0
group by v.vst_zonecode
***************************************用例END****************************************
===========================參考資料================================================
Oracle中如何計(jì)算時(shí)間差
計(jì)算時(shí)間差是Oracle DATA數(shù)據(jù)類(lèi)型的一個(gè)常見(jiàn)問(wèn)題。Oracle支持日期計(jì)算,你可以創(chuàng)建諸如“日期1-日期2”這樣的表達(dá)式來(lái)計(jì)算這兩個(gè)日期之間的時(shí)間差。
一旦你發(fā)現(xiàn)了時(shí)間差異,你可以使用簡(jiǎn)單的技巧來(lái)以天、小時(shí)、分鐘或者秒為單位來(lái)計(jì)算時(shí)間差。為了得到數(shù)據(jù)差,你必須選擇合適的時(shí)間度量單位,這樣就可以進(jìn)行數(shù)據(jù)格式隱藏。
使用完善復(fù)雜的轉(zhuǎn)換函數(shù)來(lái)轉(zhuǎn)換日期是一個(gè)誘惑,但是你會(huì)發(fā)現(xiàn)這不是最好的解決方法。
round(to_number(end-date-start_date))- 消逝的時(shí)間(以天為單位)
round(to_number(end-date-start_date)*24)- 消逝的時(shí)間(以小時(shí)為單位)
round(to_number(end-date-start_date)*1440)- 消逝的時(shí)間(以分鐘為單位)
顯示時(shí)間差的默認(rèn)模式是什么?為了找到這個(gè)問(wèn)題的答案,讓我們進(jìn)行一個(gè)簡(jiǎn)單的SQL *Plus查詢(xún)。
SQL> select sysdate-(sysdate-3) from dual;
SYSDATE-(SYSDATE-3)
-------------------
3
這里,我們看到了Oracle使用天來(lái)作為消逝時(shí)間的單位,所以我們可以很容易的使用轉(zhuǎn)換函數(shù)來(lái)把它轉(zhuǎn)換成小時(shí)或者分鐘。然而,當(dāng)分鐘數(shù)不是一個(gè)整數(shù)時(shí),我們就會(huì)遇到放置小數(shù)點(diǎn)的問(wèn)題。
Select
(sysdate-(sysdate-3.111))*1440
from
dual;
(SYSDATE-(SYSDATE-3.111))*1440
------------------------------
4479.83333
當(dāng)然,我們可以用ROUND函數(shù)(即取整函數(shù))來(lái)解決這個(gè)問(wèn)題,但是要記住我們必須首先把DATE數(shù)據(jù)類(lèi)型轉(zhuǎn)換成NUMBER數(shù)據(jù)類(lèi)型。
Select
round(to_number(sysdate-(sysdate-3.111))*1440)
from
dual;
ROUND(TO_NUMBER(SYSDATE-(SYSDATE-3.111))*1440)
----------------------------------------------
4480
我們可以用這些函數(shù)把一個(gè)消逝時(shí)間近似轉(zhuǎn)換成分鐘并把這個(gè)值寫(xiě)入Oracle表格中。在這個(gè)例子里,我們有一個(gè)離線(xiàn)(logoff)系統(tǒng)級(jí)觸發(fā)機(jī)制來(lái)計(jì)算已經(jīng)開(kāi)始的會(huì)話(huà)時(shí)間并把它放入一個(gè)Oracle STATSPACK USER_LOG擴(kuò)展表格之中。
Update
perfstat.stats$user_log
set
elapsed_minutes =
round(to_number(logoff_time-logon_time)*1440)
where
user = user_id
and
elapsed_minutes is NULL;
posted on 2007-06-05 18:44
阿偉 閱讀(346)
評(píng)論(0) 編輯 收藏 所屬分類(lèi):
DateBase