oracle日期相減
2012-02-10 12:18
--MONTHS_BETWEEN(date2,date1)?
給出date2-date1的月份?
SQL> select months_between('19-12月-1999','19-3月-1999') mon_between from dual;?
MON_BETWEEN?
-----------?
9?
SQL>select months_between(to_date('2000.05.20','yyyy.mm.dd'),to_date('2005.05.20','yyyy.dd')) mon_betw from dual;?
MON_BETW?
---------?
-60?
Oracle計算時間差表達式?
--獲取兩時間的相差豪秒數?
select ceil((To_date('2008-05-02 00:00:00' , 'yyyy-mm-dd hh24-mi-ss') - To_date('2008-04-30 23:59:59' , 'yyyy-mm-dd hh24-mi-ss')) * 24 * 60 * 60 * 1000) 相差豪秒數 FROM DUAL;?
/*?
相差豪秒數?
----------?
86401000?
1 row selected?
*/?
--獲取兩時間的相差秒數?
select ceil((To_date('2008-05-02 00:00:00' , 'yyyy-mm-dd hh24-mi-ss') - To_date('2008-04-30 23:59:59' , 'yyyy-mm-dd hh24-mi-ss')) * 24 * 60 * 60) 相差秒數 FROM DUAL;?
/*?
相差秒數?
----------?
86401?
1 row selected?
*/?
--獲取兩時間的相差分鐘數?
Date型
select ceil(((To_date('2008-05-02 00:00:00' , 'yyyy-mm-dd hh24-mi-ss') - To_date('2008-04-30 23:59:59' , 'yyyy-mm-dd hh24-mi-ss'))) * 24 * 60) 相差分鐘數 FROM DUAL;?
TIMESTAMP(6)型
select t.CALORIE_CONSUMING CALORIECONSUMING ,t.WRITE_DATE WRITEDATE ,t.START_TIME START_TIME ,t.END_TIME END_TIME
,ceil(((To_date(TO_CHAR(t.END_TIME ,'yyyy-mm-dd hh24-mi-ss') , 'yyyy-mm-dd hh24-mi-ss') - To_date(TO_CHAR(t.START_TIME ,'yyyy-mm-dd hh24-mi-ss') , 'yyyy-mm-dd hh24-mi-ss'))) * 24 * 60) duration
?FROM T_Sports t where 1=1 and t.IS_DELETE=0 and t.USER_ID=?
order by t.WRITE_DATE desc,t.WRITE_TIME asc) tsp group by tsp.WRITEDATE order by tsp.WRITEDATE desc
/*?
相差分鐘數?
----------?
1441?
1 row selected?
*/?
--獲取兩時間的相差小時數?
select ceil((To_date('2008-05-02 00:00:00' , 'yyyy-mm-dd hh24-mi-ss') - To_date('2008-04-30 23:59:59' , 'yyyy-mm-dd hh24-mi-ss')) * 24) 相差小時數 FROM DUAL;?
/*?
相差小時數?
----------?
25?
1 row selected?
*/?
--獲取兩時間的相差天數?
select ceil((To_date('2008-05-02 00:00:00' , 'yyyy-mm-dd hh24-mi-ss') - To_date('2008-04-30 23:59:59' , 'yyyy-mm-dd hh24-mi-ss'))) 相差天數 FROM DUAL;?
/*?
相差天數?
----------?
2?
1 row selected?
*/?
----------------------------------------?
注:天數可以2個日期直接減,這樣更加方便?
----------------------------------------?
--獲取兩時間月份差?
select (EXTRACT(year FROM to_date('2009-05-01','yyyy-mm-dd')) - EXTRACT(year FROM to_date('2008-04-30','yyyy-mm-dd'))) * 12 +
EXTRACT(month FROM to_date('2008-05-01','yyyy-mm-dd')) - EXTRACT(month FROM to_date('2008-04-30','yyyy-mm-dd')) months?
from dual;?
/*?
MONTHS?
----------?
13?
1 row selected?
*/?
--------------------------------------?
注:可以使用months_between函數,更加方便?
--------------------------------------?
--獲取兩時間年份差?
select EXTRACT(year FROM to_date('2009-05-01','yyyy-mm-dd')) - EXTRACT(year FROM to_date('2008-04-30','yyyy-mm-dd')) years from dual;?
/*?
YEARS?
----------?
1?
select sysdate,add_months(sysdate,12) from dual; --加1年?
select sysdate,add_months(sysdate,1) from dual; --加1月?
select sysdate,TO_CHAR(sysdate+7,'yyyy-mm-dd HH24:MI:SS') from dual; --加1星期?
select sysdate,TO_CHAR(sysdate+1,'yyyy-mm-dd HH24:MI:SS') from dual; --加1天?
select sysdate,TO_CHAR(sysdate+1/24,'yyyy-mm-dd HH24:MI:SS') from dual; --加1小時?
select sysdate,TO_CHAR(sysdate+1/24/60,'yyyy-mm-dd HH23:MI:SS') from dual; --加1分鐘?
select sysdate,TO_CHAR(sysdate+1/24/60/60,'yyyy-mm-dd HH23:MI:SS') from dual; --加1秒?
select sysdate+7 from dual; --加7天
將當前日期轉換為上一個月
SELECT TO_CHAR(ADD_MONTHS(SYSDATE, -1), 'yyyymm') --獲取當前時間的前一個月
FROM DUAL;
select sysdate from dual; /**獲取當前時間到秒**/
select sysdate-3 from dual;/**獲取當前2天**/
select round(sysdate) as 格式成日期 from dual;
select to_date('2008-9-2','yyyy_mm_dd') as 格式成日期 from dual;
SELECT TO_CHAR(ADD_MONTHS(SYSDATE, -1), 'yyyymm') FROM DUAL; /**--獲取當前時間的前一個月,正向后**/
Select last_day(sysdate) from dual;/**本月最受一天**/
/***分別取時間的年、月、日***/
Select to_char(sysdate,'YYYY') from dual;
select to_char(sysdate,'mm') from dual;
select to_char(sysdate,'dd') from dual;
一下是轉載 jenry-云飛揚:
1。上月末天:
SQL> select to_char(add_months(last_day(sysdate),-1),'yyyy-MM-dd') LastDay from
dual;
LASTDAY
----------
2005-05-31
2。上月今天
SQL> select to_char(add_months(sysdate,-1),'yyyy-MM-dd') PreToday from dual;
PRETODAY
----------
2005-05-21
3.上月首天
SQL> select to_char(add_months(last_day(sysdate)+1,-2),'yyyy-MM-dd') firstDay from dual;
FIRSTDAY
----------
2005-05-01
4.按照每周進行統計
SQL> select to_char(sysdate,'ww') from dual group by to_char(sysdate,'ww');
TO
--
25
5。按照每月進行統計
SQL> select to_char(sysdate,'mm') from dual group by to_char(sysdate,'mm');
TO
--
06
6。按照每季度進行統計
SQL> select to_char(sysdate,'q') from dual group by to_char(sysdate,'q');
T
-
2
7。按照每年進行統計
SQL> select to_char(sysdate,'yyyy') from dual group by to_char(sysdate,'yyyy');
TO_C
----
2005
8.要找到某月中所有周五的具體日期?
select to_char(t.d,'YY-MM-DD') from (?
select trunc(sysdate, 'MM')+rownum-1 as d?
from dba_objects?
where rownum < 32) t?
where to_char(t.d, 'MM') = to_char(sysdate, 'MM') --找出當前月份的周五的日期
and trim(to_char(t.d, 'Day')) = '星期五'?
--------?
03-05-02?
03-05-09?
03-05-16?
03-05-23?
03-05-30?
如果把where to_char(t.d, 'MM') = to_char(sysdate, 'MM')改成sysdate-90,即為查找當前月份的前三個月中的每周五的日期。
9.oracle中時間運算
內容如下:?
1、oracle支持對日期進行運算?
2、日期運算時是以天為單位進行的?
3、當需要以分秒等更小的單位算值時,按時間進制進行轉換即可?
4、進行時間進制轉換時注意加括號,否則會出問題
SQL> alter session set nls_date_format='yyyy-mm-dd hh:mi:ss';
會話已更改。
SQL> set serverout on?
SQL> declare?
2 DateValue date;?
3 begin?
4 select sysdate into DateValue from dual;?
5 dbms_output.put_line('源時間:'||to_char(DateValue));?
6 dbms_output.put_line('源時間減1天:'||to_char(DateValue-1));?
7 dbms_output.put_line('源時間減1天1小時:'||to_char(DateValue-1-1/24));?
8 dbms_output.put_line('源時間減1天1小時1分:'||to_char(DateValue-1-1/24-1/(24*60)));?
9 dbms_output.put_line('源時間減1天1小時1分1秒:'||to_char(DateValue-1-1/24-1/(24*60)-1/(24*60*60)));?
10 end;?
11 /?
源時間:2003-12-29 11:53:41?
源時間減1天:2003-12-28 11:53:41?
源時間減1天1小時:2003-12-28 10:53:41?
源時間減1天1小時1分:2003-12-28 10:52:41?
源時間減1天1小時1分1秒:2003-12-28 10:52:40
PL/SQL 過程已成功完成。
在Oracle中實現時間相加處理
-- 名稱:Add_Times
-- 功能:返回d1與NewTime相加以后的結果,實現時間的相加
-- 說明:對于NewTime中的日期不予考慮
-- 日期:2004-12-07
-- 版本:1.0
-- 作者:Kevin
create or replace function Add_Times(d1 in date,NewTime in date) return date?
is
hh number;
mm number;
ss number;
hours number;
dResult date;?
begin
-- 下面依次取出時、分、秒
select to_number(to_char(NewTime,'HH24')) into hh from dual;
select to_number(to_char(NewTime,'MI')) into mm from dual;
select to_number(to_char(NewTime,'SS')) into ss from dual;
-- 換算出NewTime中小時總和,在一天的百分幾
hours := (hh + (mm / 60) + (ss / 3600))/ 24;
-- 得出時間相加后的結果
select d1 + hours into dResult from dual;
return(dResult);
end Add_Times;
-- 測試用例
-- select Add_Times(sysdate,to_date('2004-12-06 03:23:00','YYYY-MM-DD HH24:MI:SS')) from dual
在Oracle9i中計算時間差
計算時間差是Oracle DATA數據類型的一個常見問題。Oracle支持日期計算,你可以創建諸如“日期1-日期2”這樣的表達式來計算這兩個日期之間的時間差。?
一旦你發現了時間差異,你可以使用簡單的技巧來以天、小時、分鐘或者秒為單位來計算時間差。為了得到數據差,你必須選擇合適的時間度量單位,這樣就可以進行數據格式隱藏。?
使用完善復雜的轉換函數來轉換日期是一個誘惑,但是你會發現這不是最好的解決方法。?
round(to_number(end-date-start_date))- 消逝的時間(以天為單位)?
round(to_number(end-date-start_date)*24)- 消逝的時間(以小時為單位)?
round(to_number(end-date-start_date)*1440)- 消逝的時間(以分鐘為單位)?
顯示時間差的默認模式是什么?為了找到這個問題的答案,讓我們進行一個簡單的SQL *Plus查詢。?
SQL> select sysdate-(sysdate-3) from dual;?
SYSDATE-(SYSDATE-3)?
-------------------?
3?
這里,我們看到了Oracle使用天來作為消逝時間的單位,所以我們可以很容易的使用轉換函數來把它轉換成小時或者分鐘。然而,當分鐘數不是一個整數時,我們就會遇到放置小數點的問題。?
Select?
(sysdate-(sysdate-3.111))*1440?
from?
dual;?
(SYSDATE-(SYSDATE-3.111))*1440?
------------------------------?
4479.83333?
當然,我們可以用ROUND函數(即取整函數)來解決這個問題,但是要記住我們必須首先把DATE數據類型轉換成NUMBER數據類型。?
Select?
round(to_number(sysdate-(sysdate-3.111))*1440)?
from?
dual;?
ROUND(TO_NUMBER(SYSDATE-(SYSDATE-3.111))*1440)?
----------------------------------------------?
4480?
我們可以用這些函數把一個消逝時間近似轉換成分鐘并把這個值寫入Oracle表格中。在這個例子里,我們有一個離線(logoff)系統級觸發機制來計算已經開始的會話時間并把它放入一個Oracle STATSPACK USER_LOG擴展表格之中。?
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;
查出任一年月所含的工作日
CREATE OR REPLACE FUNCTION Get_WorkingDays(
ny IN VARCHAR2
) RETURN INTEGER IS
/*------------------------------------------------------------------------------------------
函數名稱:Get_WorkingDays
中文名稱:求某一年月中共有多少工作日
作者姓名: XINGPING
編寫時間: 2004-05-22
輸入參數:NY:所求包含工作日數的年月,格式為yyyymm,如200405
返 回 值:整型值,包含的工作日數目。
算法描述:
1).列舉出參數給出的年月中的每一天。這里使用了一個表(ljrq是我的庫中的一張表。這個表可以是有權訪問的、記錄條數至少為31的任意一張表或視圖)來構造出某年月的每一天。
2).用這些日期和一個已知星期幾的日期相減(2001-12-30是星期天),所得的差再對7求模。如果所求年月在2001-12-30以前,那么所得的差既是負數,求模后所得值范圍為大于-6,小于0,如-1表示星期六,故先將求模的結果加7,再求7的模.
3).過濾掉結果集中值為0和6的元素,然后求count,所得即為工作日數目。?
-------------------------------------------------------------------------------------------------*/
Result INTEGER;
BEGIN
SELECT COUNT(*) INTO Result
FROM (SELECT MOD(MOD(q.rq-to_date('2001-12-30','yyyy-mm-dd'),7),7) weekday
FROM ( SELECT to_date(ny||t.dd,'yyyymmdd') rq
FROM (SELECT substr(100+ROWNUM,2,2) dd?
FROM ljrq z WHERE Rownum<=31
) t
WHERE to_date(ny||t.dd,'yyyymmdd')?
BETWEEN to_date(ny,'yyyymm')?
AND last_day(to_date(ny,'yyyymm'))
)q
) a?
WHERE a.weekday NOT IN(0,6);?
RETURN Result;?
END Get_WorkingDays;
______________________________________
還有一個版本
CREATE OR REPLACE FUNCTION Get_WorkingDays(
ny IN VARCHAR2
) RETURN INTEGER IS
/*-----------------------------------------------------------------------------------------
函數名稱:Get_WorkingDays
中文名稱:求某一年月中共有多少工作日
作者姓名: XINGPING
編寫時間: 2004-05-23
輸入參數:NY:所求包含工作日數的年月,格式為yyyymm,如200405
返 回 值:整型值,包含的工作日數目。
算法描述:使用Last_day函數計算出參數所給年月共包含多少天,根據這個值來構造一個循環。在這個循環中先求這個月的每一天與一個已知是星期天的日期(2001-12-30是星期天)的差,所得的差再對7求模。如果所求日期在2001-12-30以前,那么所得的差既是負數,求模后所得值范圍為大于-6,小于0,如-1表示星期六,故先將求模的結果加7,再求7的模. 如過所得值不等于0和6(即不是星期六和星期天),則算一個工作日。?
----------------------------------------------------------------------------------------*/
Result INTEGER := 0;
myts INTEGER; --所給年月的天數
scts INTEGER; --某天距2001-12-30所差的天數
rq DATE;
djt INTEGER := 1; --?
BEGIN
myts := to_char(last_day(to_date(ny,'yyyymm')),'dd');?
LOOP?
rq := TO_date(ny||substr(100+djt,2),'yyyymmdd');
scts := rq - to_date('2001-12-30','yyyy-mm-dd');
IF MOD(MOD(scts,7)+7,7) NOT IN(0,6) THEN
Result := Result + 1;
END IF;
djt := djt + 1;?
EXIT WHEN djt>myts;
END LOOP;?
RETURN Result;?
END Get_WorkingDays;
以上兩個版本的比較
第一個版本一條SQL語句就可以得出結果,不需要編程就可以達到目的。但需要使用任意一張有權訪問的、記錄條數至少為31的一張表或視圖。
第二個版本需要編程,但不需要表或者視圖。
這兩個版本都還存在需要完善的地方,即沒有考慮節日,如五一、十一、元旦、春節這些節假期都沒有去除。這些節假日應該維護成一張表,然后通過查表來去除這些節假日。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
