天天看點

oracle中一些sql以及存儲過程小積累(轉)

将目前日期轉換為上一個月

  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');

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資料類型。

    round(to_number(sysdate-(sysdate-3.111))*1440)

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;

  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;

______________________________________

還有一個版本

/*-----------------------------------------------------------------------------------------

編寫時間: 2004-05-23

算法描述:使用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;   --

  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; 

以上兩個版本的比較

第一個版本一條sql語句就可以得出結果,不需要程式設計就可以達到目的。但需要使用任意一張有權通路的、記錄條數至少為31的一張表或視圖。

    第二個版本需要程式設計,但不需要表或者視圖。

    這兩個版本都還存在需要完善的地方,即沒有考慮節日,如五一、十一、元旦、春節這些節假期都沒有去除。這些節假日應該維護成一張表,然後通過查表來去除這些節假日。