天天看点

ORACLE日期时间函数查询 --Zechong.Wang

TO_DATE格式(以时间:2007-11-02 13:45:25为例)

Year:

yy two digits 两位年 显示值:07

yyy three digits 三位年 显示值:007

yyyy four digits 四位年 显示值:2007

Month:

mm number 两位月 显示值:11

mon abbreviated 字符集表示 显示值:11月,若是英文版,显示nov

month spelled out 字符集表示 显示值:11月,若是英文版,显示november

Day:      
dd    number         当月第几天        显示值:02
ddd    number         当年第几天        显示值:02
dy    abbreviated 当周第几天简写    显示值:星期五,若是英文版,显示fri
day    spelled out   当周第几天全写    显示值:星期五,若是英文版,显示friday        
ddspth spelled out, ordinal twelfth 
     
      Hour:
      hh    two digits 12小时进制            显示值:01
      hh24 two digits 24小时进制            显示值:13
      
      Minute:
      mi    two digits 60进制                显示值:45
      
      Second:
      ss    two digits 60进制                显示值:25
      
      其它
      Q     digit         季度                  显示值:4
      WW    digit         当年第几周            显示值:44
      W    digit          当月第几周            显示值:1
      
24小时格式下时间范围为: 0:00:00 - 23:59:59....      
12小时格式下时间范围为: 1:00:00 - 12:59:59 .... 
           
  1. 日期和字符转换函数用法(to_date,to_char)

    select to_char(sysdate,‘yyyy-mm-dd hh24:mi:ss’) as nowTime from dual; //日期转化为字符串

    select to_char(sysdate,‘yyyy’) as nowYear from dual; //获取时间的年

    select to_char(sysdate,‘mm’) as nowMonth from dual; //获取时间的月

    select to_char(sysdate,‘dd’) as nowDay from dual; //获取时间的日

    select to_char(sysdate,‘hh24’) as nowHour from dual; //获取时间的时

    select to_char(sysdate,‘mi’) as nowMinute from dual; //获取时间的分

    select to_char(sysdate,‘ss’) as nowSecond from dual; //获取时间的秒

    select to_date(‘2004-05-07 13:23:44’,‘yyyy-mm-dd hh24:mi:ss’) from dual//

2.select to_char( to_date(222,‘J’),‘Jsp’) from dual

显示Two Hundred Twenty-Two

3.求某天是星期几

select to_char(to_date(‘2002-08-26’,‘yyyy-mm-dd’),‘day’) from dual;

星期一

select to_char(to_date(‘2002-08-26’,‘yyyy-mm-dd’),‘day’,‘NLS_DATE_LANGUAGE = American’) from dual;

monday

设置日期语言

ALTER SESSION SET NLS_DATE_LANGUAGE=‘AMERICAN’;

也可以这样

TO_DATE (‘2002-08-26’, ‘YYYY-mm-dd’, ‘NLS_DATE_LANGUAGE = American’)

  1. 两个日期间的天数

    select floor(sysdate - to_date(‘20020405’,‘yyyymmdd’)) from dual;

  2. 时间为null的用法

    select id, active_date from table1

    UNION

    select 1, TO_DATE(null) from dual;

    注意要用TO_DATE(null)

6.月份差

a_date between to_date(‘20011201’,‘yyyymmdd’) and to_date(‘20011231’,‘yyyymmdd’)

那么12月31号中午12点之后和12月1号的12点之前是不包含在这个范围之内的。

所以,当时间需要精确的时候,觉得to_char还是必要的

  1. 日期格式冲突问题

    输入的格式要看你安装的ORACLE字符集的类型, 比如: US7ASCII, date格式的类型就是: ‘01-Jan-01’

    alter system set NLS_DATE_LANGUAGE = American

    alter session set NLS_DATE_LANGUAGE = American

    或者在to_date中写

    select to_char(to_date(‘2002-08-26’,‘yyyy-mm-dd’),‘day’,‘NLS_DATE_LANGUAGE = American’) from dual;

    注意我这只是举了NLS_DATE_LANGUAGE,当然还有很多,

    可查看

    select * from nls_session_parameters

    select * from V$NLS_PARAMETERS

8.select count(*)

from ( select rownum-1 rnum      
       from all_objects      
       where rownum <= to_date('2002-02-28','yyyy-mm-dd') - to_date('2002-      
       02-01','yyyy-mm-dd')+1      
      )      
   where to_char( to_date('2002-02-01','yyyy-mm-dd')+rnum-1, 'D' )      
        not in ( '1', '7' )    
           

查找2002-02-28至2002-02-01间除星期一和七的天数

在前后分别调用DBMS_UTILITY.GET_TIME, 让后将结果相减(得到的是1/100秒, 而不是毫秒).

  1. 查找月份
    select months_between(to_date('01-31-1999','MM-DD-YYYY'),to_date('12-31-1998','MM-DD-YYYY')) "MONTHS" FROM DUAL;      
     1      
    select months_between(to_date('02-01-1999','MM-DD-YYYY'),to_date('12-31-1998','MM-DD-YYYY')) "MONTHS" FROM DUAL;      
     1.03225806451613 
               
  2. Next_day的用法

    Next_day(date, day)

    Monday-Sunday, for format code DAY

    Mon-Sun, for format code DY

    1-7, for format code D

11.select to_char(sysdate,‘hh:mi:ss’) TIME from all_objects

注意:第一条记录的TIME 与最后一行是一样的

可以建立一个函数来处理这个问题

create or replace function sys_date return date is      
   begin      
   return sysdate;      
   end;        
   select to_char(sys_date,'hh:mi:ss') from all_objects;  
           

12.获得小时数

extract()找出日期或间隔值的字段值

SELECT EXTRACT(HOUR FROM TIMESTAMP ‘2001-02-16 2:38:40’) from offer

SQL> select sysdate ,to_char(sysdate,‘hh’) from dual;

SYSDATE TO_CHAR(SYSDATE,‘HH’)

-------------------- ---------------------

2003-10-13 19:35:21 07

SQL> select sysdate ,to_char(sysdate,'hh24') from dual;      
SYSDATE TO_CHAR(SYSDATE,'HH24')      
-------------------- -----------------------      
2003-10-13 19:35:21 19    
           

13.年月日的处理

select older_date,      
       newer_date,      
       years,      
       months,      
       abs(      
        trunc(      
         newer_date-      
         add_months( older_date,years*12+months )      
        )      
       ) days 
       
   from ( select      
        trunc(months_between( newer_date, older_date )/12) YEARS,      
        mod(trunc(months_between( newer_date, older_date )),12 ) MONTHS,      
        newer_date,      
        older_date      
        from ( 
              select hiredate older_date, add_months(hiredate,rownum)+rownum newer_date      
              from emp 
             )      
      )    
           

14.处理月份天数不定的办法

select to_char(add_months(last_day(sysdate) +1, -2), ‘yyyymmdd’),last_day(sysdate) from dual

16.找出今年的天数

select add_months(trunc(sysdate,‘year’), 12) - trunc(sysdate,‘year’) from dual

闰年的处理方法

to_char( last_day( to_date(‘02’ | | :year,‘mmyyyy’) ), ‘dd’ )

如果是28就不是闰年

17.yyyy与rrrr的区别

'YYYY99 TO_C      
   ------- ----      
   yyyy 99 0099      
   rrrr 99 1999      
   yyyy 01 0001      
   rrrr 01 2001
           

18.不同时区的处理

select to_char( NEW_TIME( sysdate, 'GMT','EST'), 'dd/mm/yyyy hh:mi:ss') ,sysdate      
   from dual;    
           

19.5秒钟一个间隔

Select TO_DATE(FLOOR(TO_CHAR(sysdate,'SSSSS')/300) * 300,'SSSSS') ,TO_CHAR(sysdate,'SSSSS')      
   from dual    
   2002-11-1 9:55:00 35786      
   SSSSS表示5位秒数    
           

20.一年的第几天

select TO_CHAR(SYSDATE,'DDD'),sysdate from dual     
   310 2002-11-6 10:03:51   
           

21.计算小时,分,秒,毫秒

select      
     Days,      
     A,      
     TRUNC(A*24) Hours,      
     TRUNC(A*24*60 - 60*TRUNC(A*24)) Minutes,      
     TRUNC(A*24*60*60 - 60*TRUNC(A*24*60)) Seconds,      
     TRUNC(A*24*60*60*100 - 100*TRUNC(A*24*60*60)) mSeconds      
    from      
    (      
     select      
     trunc(sysdate) Days,      
     sysdate - trunc(sysdate) A      
     from dual      
   )    

   select * from tabname      
   order by decode(mode,'FIFO',1,-1)*to_char(rq,'yyyymmddhh24miss');      
   //      
   floor((date2-date1) /365) 作为年      
   floor((date2-date1, 365) /30) 作为月      
   d(mod(date2-date1, 365), 30)作为日.
           

23.next_day函数 返回下个星期的日期,day为1-7或星期日-星期六,1表示星期日

next_day(sysdate,6)是从当前开始下一个星期五。后面的数字是从星期日开始算起。      
   1 2 3 4 5 6 7      
   日 一 二 三 四 五 六     
           

select (sysdate-to_date(‘2003-12-03 12:55:45’,‘yyyy-mm-dd hh24:mi:ss’))2460*60 from ddual

日期 返回的是天 然后 转换为ss

24,round舍入到最接近的日期

select sysdate S1,
   round(sysdate) S2 ,
   round(sysdate,'year') YEAR,
   round(sysdate,'month') MONTH ,
   round(sysdate,'day') DAY from dual
           

25,trunc[截断到最接近的日期,单位为天] ,返回的是日期类型

select sysdate S1,                     
     trunc(sysdate) S2,                 //返回当前日期,无时分秒
     trunc(sysdate,'year') YEAR,        //返回当前年的1月1日,无时分秒
     trunc(sysdate,'month') MONTH ,     //返回当前月的1日,无时分秒
     trunc(sysdate,'day') DAY           //返回当前星期的星期天,无时分秒
   from dual
           

26,返回日期列表中最晚日期

select greatest(‘01-1月-04’,‘04-1月-04’,‘10-2月-04’) from dual

27.计算时间差

注:oracle时间差是以天数为单位,所以换算成年月,日

select floor(to_number(sysdate-to_date('2007-11-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))/365) as spanYears from dual //时间差-年
  select ceil(moths_between(sysdate-to_date('2007-11-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))) as spanMonths from dual //时间差-月
  select floor(to_number(sysdate-to_date('2007-11-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))) as spanDays from dual //时间差-天
  select floor(to_number(sysdate-to_date('2007-11-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))*24) as spanHours from dual //时间差-时
  select floor(to_number(sysdate-to_date('2007-11-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))*24*60) as spanMinutes from dual //时间差-分
  select floor(to_number(sysdate-to_date('2007-11-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))*24*60*60) as spanSeconds from dual //时间差-秒
           

28.更新时间

注:oracle时间加减是以天数为单位,设改变量为n,所以换算成年月,日

select to_char(sysdate,‘yyyy-mm-dd hh24:mi:ss’),to_char(sysdate+n*365,‘yyyy-mm-dd hh24:mi:ss’) as newTime from dual //改变时间-年

select to_char(sysdate,‘yyyy-mm-dd hh24:mi:ss’),add_months(sysdate,n) as newTime from dual //改变时间-月

select to_char(sysdate,‘yyyy-mm-dd hh24:mi:ss’),to_char(sysdate+n,‘yyyy-mm-dd hh24:mi:ss’) as newTime from dual //改变时间-日

select to_char(sysdate,‘yyyy-mm-dd hh24:mi:ss’),to_char(sysdate+n/24,‘yyyy-mm-dd hh24:mi:ss’) as newTime from dual //改变时间-时

select to_char(sysdate,‘yyyy-mm-dd hh24:mi:ss’),to_char(sysdate+n/24/60,‘yyyy-mm-dd hh24:mi:ss’) as newTime from dual //改变时间-分

select to_char(sysdate,‘yyyy-mm-dd hh24:mi:ss’),to_char(sysdate+n/24/60/60,‘yyyy-mm-dd hh24:mi:ss’) as newTime from dual //改变时间-秒

29.查找月的第一天,最后一天

SELECT Trunc(Trunc(SYSDATE, 'MONTH') - 1, 'MONTH') First_Day_Last_Month,
       Trunc(SYSDATE, 'MONTH') - 1 / 86400 Last_Day_Last_Month,
       Trunc(SYSDATE, 'MONTH') First_Day_Cur_Month,
       LAST_DAY(Trunc(SYSDATE, 'MONTH')) + 1 - 1 / 86400 Last_Day_Cur_Month
   FROM dual;
           

三. 字符函数(可用于字面字符或数据库列)

1,字符串截取

select substr(‘abcdef’,1,3) from dual

2,查找子串位置

select instr(‘abcfdgfdhd’,‘fd’) from dual

3,字符串连接

select ‘HELLO’||‘hello world’ from dual;

4, 1)去掉字符串中的空格

select ltrim(' abc') s1,
rtrim('zhang ') s2,
trim(' zhang ') s3 from dual
           

2)去掉前导和后缀

select trim(leading 9 from 9998767999) s1,
    trim(trailing 9 from 9998767999) s2,
    trim(9 from 9998767999) s3 from dual;
           

5,返回字符串首字母的Ascii值

select ascii(‘a’) from dual

6,返回ascii值对应的字母

select chr(97) from dual

7,计算字符串长度

select length(‘abcdef’) from dual

8,initcap(首字母变大写) ,lower(变小写),upper(变大写)

select lower('ABC') s1, 
       upper('def') s2, 
       initcap('efg') s3
   from dual;
           

9,Replace

select replace(‘abc’,‘b’,‘xy’) from dual;

10,translate

select translate(‘abc’,‘b’,‘xx’) from dual; – x是1位

11,lpad [左添充] rpad 右填充

select lpad(‘func’,15,’=’) s1, rpad(‘func’,15,’-’) s2 from dual;

select lpad(dname,14,’=’) from dept;

12, decode[实现if …then 逻辑] 注:第一个是表达式,最后一个是不满足任何一个条件的值

select deptno,decode(deptno,10,'1',20,'2',30,'3','其他') from dept;
   例:
   select seed,account_name,decode(seed,111,1000,200,2000,0) from t_userInfo//如果seed为111,则取1000;为200,取2000;其它取0
   select seed,account_name,decode(sign(seed-111),1,'big seed',-1,'little seed','equal seed') from t_userInfo//如果seed>111,则显示大;为200,则显示小;其它则显示相等
           

13 case[实现switch …case 逻辑]

SELECT CASE X-FIELD 
         WHEN X-FIELD < 40 THEN 'X-FIELD 小于 40'
         WHEN X-FIELD < 50 THEN 'X-FIELD 小于 50'
         WHEN X-FIELD < 60 THEN 'X-FIELD 小于 60'
         ELSE 'UNBEKNOWN'
        END
   FROM DUAL
           

注:CASE语句在处理类似问题就显得非常灵活。当只是需要匹配少量数值时,用Decode更为简洁。

四.数字函数

1,取整函数(ceil 向上取整,floor 向下取整)

select ceil(66.6) N1,floor(66.6) N2 from dual;

2, 取幂(power) 和 求平方根(sqrt)

select power(3,2) N1,sqrt(9) N2 from dual;

3,求余

select mod(9,5) from dual;

4,返回固定小数位数 (round:四舍五入,trunc:直接截断)

select round(66.667,2) N1,trunc(66.667,2) N2 from dual;

5,返回值的符号(正数返回为1,负数为-1)

select sign(-32),sign(293) from dual;

五.转换函数

1,to_char()[将日期和数字类型转换成字符类型]

1) select to_char(sysdate) s1,
        to_char(sysdate,'yyyy-mm-dd') s2,
        to_char(sysdate,'yyyy') s3,
        to_char(sysdate,'yyyy-mm-dd hh12:mi:ss') s4,
        to_char(sysdate, 'hh24:mi:ss') s5,
        to_char(sysdate,'DAY') s6 
    from dual;
   2) select sal,to_char(sal,'$99999') n1,to_char(sal,'$99,999') n2 from emp
           

2, to_date()[将字符类型转换为日期类型]

insert into emp(empno,hiredate) values(8000,to_date(‘2004-10-10’,‘yyyy-mm-dd’));

3, to_number() 转换为数字类型

select to_number(to_char(sysdate,‘hh12’)) from dual; //以数字显示的小时数

六.其他函数

1.user:

返回登录的用户名称

select user from dual;

2.vsize:

返回表达式所需的字节数

select vsize(‘HELLO’) from dual;

3.nvl(ex1,ex2):  

ex1值为空则返回ex2,否则返回该值本身ex1(常用)

例:如果雇员没有佣金,将显示0,否则显示佣金

select comm,nvl(comm,0) from emp;

4.nullif(ex1,ex2):

值相等返空,否则返回第一个值

例:如果工资和佣金相等,则显示空,否则显示工资

select nullif(sal,comm),sal,comm from emp;

5.coalesce:  

返回列表中第一个非空表达式

select comm,sal,coalesce(comm,sal,sal*10) from emp;

6.nvl2(ex1,ex2,ex3) :

如果ex1不为空,显示ex2,否则显示ex3

如:查看有佣金的雇员姓名以及他们的佣金

  select nvl2(comm,ename,’) as HaveCommName,comm from emp;

七.分组函数

max min avg count sum

1,整个结果集是一个组

  1. 求部门30 的最高工资,最低工资,平均工资,总人数,有工作的人数,工种数量及工资总和
select max(ename),max(sal), 
 min(ename),min(sal),
 avg(sal),
 count(*) ,count(job),count(distinct(job)) ,
 sum(sal) from emp where deptno=30;
           

2, 带group by 和 having 的分组

1)按部门分组求最高工资,最低工资,总人数,有工作的人数,工种数量及工资总和

select deptno, max(ename),max(sal),
min(ename),min(sal),
avg(sal),
count(*) ,count(job),count(distinct(job)) ,
sum(sal) from emp group by deptno;
           

2)部门30的最高工资,最低工资,总人数,有工作的人数,工种数量及工资总和

select deptno, max(ename),max(sal),
    min(ename),min(sal),
    avg(sal),
    count(*) ,count(job),count(distinct(job)) ,
    sum(sal) from emp group by deptno having deptno=30;
           

3, stddev 返回一组值的标准偏差

select deptno,stddev(sal) from emp group by deptno;
variance 返回一组值的方差差
select deptno,variance(sal) from emp group by deptno;
           

4, 带有rollup和cube操作符的Group By

rollup 按分组的第一个列进行统计和最后的小计
    cube 按分组的所有列的进行统计和最后的小计
    select deptno,job ,sum(sal) from emp group by deptno,job;
    select deptno,job ,sum(sal) from emp group by rollup(deptno,job); 
    cube 产生组内所有列的统计和最后的小计
    select deptno,job ,sum(sal) from emp group by cube(deptno,job);
           

八、临时表

只在会话期间或在事务处理期间存在的表.

临时表在插入数据时,动态分配空间

create global temporary table temp_dept
   (dno number,
   dname varchar2(10))
   on commit delete rows;
   insert into temp_dept values(10,'ABC');
   commit;
   select * from temp_dept; --无数据显示,数据自动清除
   on commit preserve rows:在会话期间表一直可以存在(保留数据)
   on commit delete rows:事务结束清除数据(在事务结束时自动删除表的数据)
           

===========================

一、oracle sql日期比较

在今天之前:

select * from up_date where update < to_date('2007-09-07 00:00:00','yyyy-mm-dd hh24:mi:ss')
select * from up_date where update <= to_date('2007-09-07 00:00:00','yyyy-mm-dd hh24:mi:ss')
           

在今天只后:

select * from up_date where update > to_date('2007-09-07 00:00:00','yyyy-mm-dd hh24:mi:ss')
select * from up_date where update >= to_date('2007-09-07 00:00:00','yyyy-mm-dd hh24:mi:ss')
           

精确时间:

select * from up_date where update = to_date('2007-09-07 00:00:00','yyyy-mm-dd hh24:mi:ss')
           

在某段时间内:

select * from up_date where update between to_date('2007-07-07 00:00:00','yyyy-mm-dd hh24:mi:ss') and to_date('2007-09-07 00:00:00','yyyy-mm-dd hh24:mi:ss')
    select * from up_date where update < to_date('2007-09-07 00:00:00','yyyy-mm-dd hh24:mi:ss') and update > to_date('2007-07-07 00:00:00','yyyy-mm-dd hh24:mi:ss')
    select * from up_date where update <= to_date('2007-09-07 00:00:00','yyyy-mm-dd hh24:mi:ss') and update >= to_date('2007-07-07 00:00:00','yyyy-mm-dd hh24:
           

二、Oracle 获取当前日期及日期格式 获取系统日期: SYSDATE()

格式化日期:

TO_CHAR(SYSDATE(),'YY/MM/DD HH24:MI:SS)

或 TO_DATE(SYSDATE(),'YY/MM/DD HH24:MI:SS)

格式化数字:

TO_NUMBER

注: TO_CHAR 把日期或数字转换为字符串

TO_CHAR(number, ‘格式’)

TO_CHAR(salary, ‘$99,999.99’)

TO_CHAR(date, ‘格式’)

TO_DATE 把字符串转换为数据库中的日期类型

TO_DATE(char, ‘格式’)

TO_NUMBER 将字符串转换为数字

TO_NUMBER(char, ‘格式’)

返回系统日期,输出 25-12月-09

select sysdate from dual;

mi是分钟,输出 2009-12-25 14:23:31

select to_char(sysdate,‘yyyy-MM-dd HH24:mi:ss’) from dual;

mm会显示月份,输出 2009-12-25 14:12:31

select to_char(sysdate,‘yyyy-MM-dd HH24:mm:ss’) from dual;

输出 09-12-25 14:23:31

select to_char(sysdate,‘yy-mm-dd hh24:mi:ss’) from dual

输出 2009-12-25 14:23:31

select to_date(‘2009-12-25 14:23:31’,‘yyyy-mm-dd,hh24:mi:ss’) from dual

而如果把上式写作:

select to_date(‘2009-12-25 14:23:31’,‘yyyy-mm-dd,hh:mi:ss’) from dual

则会报错,因为小时hh是12进制,14为非法输入,不能匹配。

输出 $10,000,00 :

select to_char(1000000,’$99,999,99’) from dual;

输出 RMB10,000,00 :

select to_char(1000000,‘L99,999,99’) from dual;

输出 1000000.12 :

select trunc(to_number(‘1000000.123’),2) from dual;

select to_number(‘1000000.123’) from dual;

转换的格式:

表示 year 的:y 表示年的最后一位 、

yy 表示年的最后2位 、

yyy 表示年的最后3位 、

yyyy 用4位数表示年

表示month的: mm 用2位数字表示月 、

mon 用简写形式, 比如11月或者nov 、

month 用全称, 比如11月或者november

表示day的:dd 表示当月第几天 、

ddd 表示当年第几天 、

dy 当周第几天,简写, 比如星期五或者fri 、

day 当周第几天,全称, 比如星期五或者friday

表示hour的:hh 2位数表示小时 12进制、

hh24 2位数表示小时 24小时

表示minute的:mi 2位数表示分钟

表示second的:ss 2位数表示秒 60进制

表示季度的:q 一位数 表示季度 (1-4)

另外还有ww 用来表示当年第几周 w用来表示当月第几周。

24小时制下的时间范围:00:00:00-23:59:59

12小时制下的时间范围:1:00:00-12:59:59

数字格式: 9 代表一个数字

0 强制显示0

$ 放置一个$符

L 放置一个浮动本地货币符

. 显示小数点

, 显示千位指示符

补充:

当前时间减去7分钟的时间

select sysdate,sysdate - interval ‘7’ MINUTE from dual;

当前时间减去7小时的时间

select sysdate - interval ‘7’ hour from dual;

当前时间减去7天的时间

select sysdate - interval ‘7’ day from dual;

当前时间减去7月的时间

select sysdate,sysdate - interval ‘7’ month from dual;

当前时间减去7年的时间

select sysdate,sysdate - interval ‘7’ year from dual;

时间间隔乘以一个数字

select sysdate,sysdate - 8*interval ‘7’ hour from dual;

含义解释:

Dual伪列

Dual 是 Oracle中的一个实际存在的表,任何用户均可读取,常用在没有目标表的select语句块中。

不同系统可能返回日期的格式不一样。

返回当前连接的用户:select user from dual;三、前后第几天获取昨天:

select trunc(SYSDATE-1) from dual;

检查一下:

select to_char (trunc(SYSDATE-1),‘yyyy-mm-dd HH24:MI:SS’) from dual;

获取上个月第一天00:00:00:

select add_months(trunc(sysdate,‘MON’),-1) from dual

select add_months(trunc(sysdate,‘MON’),-13) from dual也可以

获取上个月今天00:00:00:

SELECT trunc(add_months(sysdate,-1))FROM dual

获得本季度第一天

SELECT TRUNC(add_months(SYSDATE,0),‘Q’) FROM dual

获得上季度第一天

SELECT TRUNC(add_months(SYSDATE,-3),‘Q’) FROM dual

获得去年1月1日

to_char(add_months(trunc(sysdate, ‘Year’), -12), ‘YYYY-MM-DD’)

between and 前面的时间小后面的时间大

to_date(‘20110105’,‘YYYYMMDD’)-7 此处 -7代表天

四、Oracle时间函数常用的时间格式 在oracle中有 yyyy-mm-dd hh24:mi:ss 而在Java中有些区别 为yyyy-MM-dd HH:mm:ss;

to_char(sysdate,‘yyyy/mm/dd hh24:mi:ss’)

常用函数及示例:

1.Sysdate 当前日期和时间

SQL> Select sysdate from dual;
SYSDATE
----------
21-6月 -05
           

2.Last_day 本月最后一天

SQL> Select last_day(sysdate) from dual;
LAST_DAY(S
----------
30-6月 -05
           

3.Add_months(d,n) 当前日期d后推n个月

用于从一个日期值增加或减少一些月份

date_value:=add_months(date_value,number_of_months)
SQL> Select add_months(sysdate,2) from dual;
ADD_MONTHS
----------
21-8月 -05
           

4.Months_between(f,s) 日期f和s间相差月数

SQL> select months_between(sysdate,to_date('2005-11-12','yyyy-mm-dd'))from dual;
MONTHS_BETWEEN(SYSDATE,TO_DATE('2005-11-12','YYYY-MM-DD'))
----------------------------------------------------------
-4.6966741 
           

5.NEXT_DAY(d, day_of_week)

返回由"day_of_week"命名的,在变量"d"指定的日期之后的第一个工作日的日期。参数"day_of_week"必须为该星期中的某一天。

SQL> SELECT next_day(to_date('20050620','YYYYMMDD'),1) FROM dual;
NEXT_DAY(T
----------
26-6月 -05
           

6.current_date()返回当前会话时区中的当前日期

date_value:=current_date 
SQL> column sessiontimezone for a15 
SQL> select sessiontimezone,current_date from dual; 
SESSIONTIMEZONE CURRENT_DA 
--------------- ---------- 
+08:00 13-11月-03 
           

SQL> alter session set time_zone=’-11:00’

2 / 会话已更改。

SQL> select sessiontimezone,current_timestamp from dual; 
SESSIONTIMEZONE CURRENT_TIMESTAMP 
--------------- ------------------------------------ 
-11:00 12-11月-03 04.59.13.668000 下午 -11:00 
           

7.current_timestamp()以timestamp with time zone数据类型返回当前会话时区中的当前日期

SQL> select current_timestamp from dual;
CURRENT_TIMESTAMP
-----------------------------------------------------------
21-6月 -05 10.13.08.220589 上午 +08:00
           

8.dbtimezone()返回时区

SQL> select dbtimezone from dual;
DBTIME
------
-08:00
           

9.extract()找出日期或间隔值的字段值

date_value:=extract(date_field from [datetime_value|interval_value]) 
SQL> select extract(month from sysdate) "This Month" from dual;
This Month
----------
6

SQL> select extract(year from add_months(sysdate,36)) " Years" from dual;
Years
----------
2008
           

10.localtimestamp()返回会话中的日期和时间

SQL> select localtimestamp from dual;
LOCALTIMESTAMP
------------------------------------------------------------
21-6月 -05 10.18.15.855652 上午
           

常用日期数据格式(该段为摘抄)

Y或YY或YYY 年的最后一位,两位或三位 Select to_char(sysdate,’YYY’) from dual; 002表示2002年

SYEAR或YEAR SYEAR使公元前的年份前加一负号 Select to_char(sysdate,’SYEAR’) from dual; -1112表示公元前111 2年

Q 季度,1~3月为第一季度 Select to_char(sysdate,’Q’) from dual; 2表示第二季度①

MM 月份数 Select to_char(sysdate,’MM’) from dual; 12表示12月

RM 月份的罗马表示 Select to_char(sysdate,’RM’) from dual; IV表示4月

Month 用9个字符长度表示的月份名 Select to_char(sysdate,’Month’) from dual; May后跟6个空格表示5月

WW 当年第几周 Select to_char(sysdate,’WW’) from dual; 24表示2002年6月13日为第24周

W 本月第几周 Select to_char(sysdate,’W’) from dual; 2002年10月1日为第1周

DDD 当年第几, 1月1日为001,2月1日为032 Select to_char(sysdate,’DDD’) from dual; 363 2002年1 2月2 9日为第363天

DD 当月第几天 Select to_char(sysdate,’DD’) from dual; 04 10月4日为第4天

D 周内第几天 Select to_char(sysdate,’D’) from dual; 5 2002年3月14日为星期一

DY 周内第几天缩写 Select to_char(sysdate,’DY’) from dual; SUN 2002年3月24日为星期天

HH或HH12 12进制小时数 Select to_char(sysdate,’HH’) from dual; 02 午夜2点过8分为02

HH24 24小时制 Select to_char(sysdate,’HH24’) from dual; 14 下午2点08分为14

MI 分钟数(0~59) Select to_char(sysdate,’MI’) from dual; 17下午4点17分

SS 秒数(0~59) Select to_char(sysdate,’SS’) from dual; 22 11点3分22秒

提示注意不要将MM格式用于分钟(分钟应该使用MI)。MM是用于月份的格式,将它用于分钟也能工作,但结果是错误的。

现在给出一些实践后的用法:

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 I
           

/-------------------------------------------------------------

函数名称: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的一张表或视图。

第二个版本需要编程,但不需要表或者视图。

这两个版本都还存在需要完善的地方,即没有考虑节日,如五一、十一、元旦、春节这些节假期都没有去除。这些节假日应该维护成一张表,然后通过查表来去除这些节假日。

继续阅读