jchunwen 2012-12-31
ORACLE日期时间函数大全
TO_DATE格式(以时间:2007-11-0213:45:25为例)
Year:
yytwodigits两位年显示值:07
yyythreedigits三位年显示值:007
yyyyfourdigits四位年显示值:2007
Month:
mmnumber两位月显示值:11
monabbreviated字符集表示显示值:11月,若是英文版,显示nov
monthspelledout字符集表示显示值:11月,若是英文版,显示november
Day:
ddnumber当月第几天显示值:02
dddnumber当年第几天显示值:02
dyabbreviated当周第几天简写显示值:星期五,若是英文版,显示fri
dayspelledout当周第几天全写显示值:星期五,若是英文版,显示friday
ddspthspelledout,ordinaltwelfth
Hour:
hhtwodigits12小时进制显示值:01
hh24twodigits24小时进制显示值:13
Minute:
mitwodigits60进制显示值:45
Second:
sstwodigits60进制显示值:25
其它
Qdigit季度显示值:4
WWdigit当年第几周显示值:44
Wdigit当月第几周显示值:1
24小时格式下时间范围为:0:00:00-23:59:59....
12小时格式下时间范围为:1:00:00-12:59:59....
1.日期和字符转换函数用法(to_date,to_char)
selectto_char(sysdate,'yyyy-mm-ddhh24:mi:ss')asnowTimefromdual;//日期转化为字符串
selectto_char(sysdate,'yyyy')asnowYearfromdual;//获取时间的年
selectto_char(sysdate,'mm')asnowMonthfromdual;//获取时间的月
selectto_char(sysdate,'dd')asnowDayfromdual;//获取时间的日
selectto_char(sysdate,'hh24')asnowHourfromdual;//获取时间的时
selectto_char(sysdate,'mi')asnowMinutefromdual;//获取时间的分
selectto_char(sysdate,'ss')asnowSecondfromdual;//获取时间的秒
selectto_date('2004-05-0713:23:44','yyyy-mm-ddhh24:mi:ss')fromdual//
2.
selectto_char(to_date(222,'J'),'Jsp')fromdual
显示TwoHundredTwenty-Two
3.求某天是星期几
selectto_char(to_date('2002-08-26','yyyy-mm-dd'),'day')fromdual;
星期一
selectto_char(to_date('2002-08-26','yyyy-mm-dd'),'day','NLS_DATE_LANGUAGE=American')fromdual;
monday
设置日期语言
ALTERSESSIONSETNLS_DATE_LANGUAGE='AMERICAN';
也可以这样
TO_DATE('2002-08-26','YYYY-mm-dd','NLS_DATE_LANGUAGE=American')
4.两个日期间的天数
selectfloor(sysdate-to_date('20020405','yyyymmdd'))fromdual;
5.时间为null的用法
selectid,active_datefromtable1
UNION
select1,TO_DATE(null)fromdual;
注意要用TO_DATE(null)
6.月份差
a_datebetweento_date('20011201','yyyymmdd')andto_date('20011231','yyyymmdd')
那么12月31号中午12点之后和12月1号的12点之前是不包含在这个范围之内的。
所以,当时间需要精确的时候,觉得to_char还是必要的
7.日期格式冲突问题
输入的格式要看你安装的ORACLE字符集的类型,比如:US7ASCII,date格式的类型就是:'01-Jan-01'
altersystemsetNLS_DATE_LANGUAGE=American
altersessionsetNLS_DATE_LANGUAGE=American
或者在to_date中写
selectto_char(to_date('2002-08-26','yyyy-mm-dd'),'day','NLS_DATE_LANGUAGE=American')fromdual;
注意我这只是举了NLS_DATE_LANGUAGE,当然还有很多,
可查看
select*fromnls_session_parameters
select*fromV$NLS_PARAMETERS
8.
selectcount(*)
from(selectrownum-1rnum
fromall_objects
whererownum<=to_date('2002-02-28','yyyy-mm-dd')-to_date('2002-
02-01','yyyy-mm-dd')+1
)
whereto_char(to_date('2002-02-01','yyyy-mm-dd')+rnum-1,'D')
notin('1','7')
查找2002-02-28至2002-02-01间除星期一和七的天数
在前后分别调用DBMS_UTILITY.GET_TIME,让后将结果相减(得到的是1/100秒,而不是毫秒).
9.查找月份
selectmonths_between(to_date('01-31-1999','MM-DD-YYYY'),to_date('12-31-1998','MM-DD-YYYY'))"MONTHS"FROMDUAL;
1
selectmonths_between(to_date('02-01-1999','MM-DD-YYYY'),to_date('12-31-1998','MM-DD-YYYY'))"MONTHS"FROMDUAL;
1.03225806451613
10.Next_day的用法
Next_day(date,day)
Monday-Sunday,forformatcodeDAY
Mon-Sun,forformatcodeDY
1-7,forformatcodeD
11
selectto_char(sysdate,'hh:mi:ss')TIMEfromall_objects
注意:第一条记录的TIME与最后一行是一样的
可以建立一个函数来处理这个问题
createorreplacefunctionsys_datereturndateis
begin
returnsysdate;
end;
selectto_char(sys_date,'hh:mi:ss')fromall_objects;
12.获得小时数
extract()找出日期或间隔值的字段值
SELECTEXTRACT(HOURFROMTIMESTAMP'2001-02-162:38:40')fromoffer
SQL>selectsysdate,to_char(sysdate,'hh')fromdual;
SYSDATETO_CHAR(SYSDATE,'HH')
-----------------------------------------
2003-10-1319:35:2107
SQL>selectsysdate,to_char(sysdate,'hh24')fromdual;
SYSDATETO_CHAR(SYSDATE,'HH24')
-------------------------------------------
2003-10-1319:35:2119
13.年月日的处理
selectolder_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(
selecthiredateolder_date,add_months(hiredate,rownum)+rownumnewer_date
fromemp
)
)
14.处理月份天数不定的办法
selectto_char(add_months(last_day(sysdate)+1,-2),'yyyymmdd'),last_day(sysdate)fromdual
16.找出今年的天数
selectadd_months(trunc(sysdate,'year'),12)-trunc(sysdate,'year')fromdual
闰年的处理方法
to_char(last_day(to_date('02'||:year,'mmyyyy')),'dd')
如果是28就不是闰年
17.yyyy与rrrr的区别
'YYYY99TO_C
-----------
yyyy990099
rrrr991999
yyyy010001
rrrr012001
18.不同时区的处理
selectto_char(NEW_TIME(sysdate,'GMT','EST'),'dd/mm/yyyyhh:mi:ss'),sysdate
fromdual;
19.5秒钟一个间隔
SelectTO_DATE(FLOOR(TO_CHAR(sysdate,'SSSSS')/300)*300,'SSSSS'),TO_CHAR(sysdate,'SSSSS')
fromdual
2002-11-19:55:0035786
SSSSS表示5位秒数
20.一年的第几天
selectTO_CHAR(SYSDATE,'DDD'),sysdatefromdual
3102002-11-610: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
fromdual
)
select*fromtabname
orderbydecode(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)是从当前开始下一个星期五。后面的数字是从星期日开始算起。
1234567
日一二三四五六
---------------------------------------------------------------
select(sysdate-to_date('2003-12-0312:55:45','yyyy-mm-ddhh24:mi:ss'))*24*60*60fromddual
日期返回的是天然后转换为ss
24,round[舍入到最接近的日期](day:舍入到最接近的星期日)
selectsysdateS1,
round(sysdate)S2,
round(sysdate,'year')YEAR,
round(sysdate,'month')MONTH,
round(sysdate,'day')DAYfromdual
25,trunc[截断到最接近的日期,单位为天],返回的是日期类型
selectsysdateS1,
trunc(sysdate)S2,//返回当前日期,无时分秒
trunc(sysdate,'year')YEAR,//返回当前年的1月1日,无时分秒
trunc(sysdate,'month')MONTH,//返回当前月的1日,无时分秒
trunc(sysdate,'day')DAY//返回当前星期的星期天,无时分秒
fromdual
26,返回日期列表中最晚日期
selectgreatest('01-1月-04','04-1月-04','10-2月-04')fromdual
27.计算时间差
注:oracle时间差是以天数为单位,所以换算成年月,日
selectfloor(to_number(sysdate-to_date('2007-11-0215:55:03','yyyy-mm-ddhh24:mi:ss'))/365)asspanYearsfromdual//时间差-年
selectceil(moths_between(sysdate-to_date('2007-11-0215:55:03','yyyy-mm-ddhh24:mi:ss')))asspanMonthsfromdual//时间差-月
selectfloor(to_number(sysdate-to_date('2007-11-0215:55:03','yyyy-mm-ddhh24:mi:ss')))asspanDaysfromdual//时间差-天
selectfloor(to_number(sysdate-to_date('2007-11-0215:55:03','yyyy-mm-ddhh24:mi:ss'))*24)asspanHoursfromdual//时间差-时
selectfloor(to_number(sysdate-to_date('2007-11-0215:55:03','yyyy-mm-ddhh24:mi:ss'))*24*60)asspanMinutesfromdual//时间差-分
selectfloor(to_number(sysdate-to_date('2007-11-0215:55:03','yyyy-mm-ddhh24:mi:ss'))*24*60*60)asspanSecondsfromdual//时间差-秒
28.更新时间
注:oracle时间加减是以天数为单位,设改变量为n,所以换算成年月,日
selectto_char(sysdate,'yyyy-mm-ddhh24:mi:ss'),to_char(sysdate+n*365,'yyyy-mm-ddhh24:mi:ss')asnewTimefromdual//改变时间-年
selectto_char(sysdate,'yyyy-mm-ddhh24:mi:ss'),add_months(sysdate,n)asnewTimefromdual//改变时间-月
selectto_char(sysdate,'yyyy-mm-ddhh24:mi:ss'),to_char(sysdate+n,'yyyy-mm-ddhh24:mi:ss')asnewTimefromdual//改变时间-日
selectto_char(sysdate,'yyyy-mm-ddhh24:mi:ss'),to_char(sysdate+n/24,'yyyy-mm-ddhh24:mi:ss')asnewTimefromdual//改变时间-时
selectto_char(sysdate,'yyyy-mm-ddhh24:mi:ss'),to_char(sysdate+n/24/60,'yyyy-mm-ddhh24:mi:ss')asnewTimefromdual//改变时间-分
selectto_char(sysdate,'yyyy-mm-ddhh24:mi:ss'),to_char(sysdate+n/24/60/60,'yyyy-mm-ddhh24:mi:ss')asnewTimefromdual//改变时间-秒
29.查找月的第一天,最后一天
SELECTTrunc(Trunc(SYSDATE,'MONTH')-1,'MONTH')First_Day_Last_Month,
Trunc(SYSDATE,'MONTH')-1/86400Last_Day_Last_Month,
Trunc(SYSDATE,'MONTH')First_Day_Cur_Month,
LAST_DAY(Trunc(SYSDATE,'MONTH'))+1-1/86400Last_Day_Cur_Month
FROMdual;
三.字符函数(可用于字面字符或数据库列)
1,字符串截取
selectsubstr('abcdef',1,3)fromdual
2,查找子串位置
selectinstr('abcfdgfdhd','fd')fromdual
3,字符串连接
select'HELLO'||'helloworld'fromdual;
4,1)去掉字符串中的空格
selectltrim('abc')s1,
rtrim('zhang')s2,
trim('zhang')s3fromdual
2)去掉前导和后缀
selecttrim(leading9from9998767999)s1,
trim(trailing9from9998767999)s2,
trim(9from9998767999)s3fromdual;
5,返回字符串首字母的Ascii值
selectascii('a')fromdual
6,返回ascii值对应的字母
selectchr(97)fromdual
7,计算字符串长度
selectlength('abcdef')fromdual
8,initcap(首字母变大写),lower(变小写),upper(变大写)
selectlower('ABC')s1,
upper('def')s2,
initcap('efg')s3
fromdual;
9,Replace
selectreplace('abc','b','xy')fromdual;
10,translate
selecttranslate('abc','b','xx')fromdual;--x是1位
11,lpad[左添充]rpad[右填充](用于控制输出格式)
selectlpad('func',15,'=')s1,rpad('func',15,'-')s2fromdual;
selectlpad(dname,14,'=')fromdept;
12,decode[实现if..then逻辑]注:第一个是表达式,最后一个是不满足任何一个条件的值
selectdeptno,decode(deptno,10,'1',20,'2',30,'3','其他')fromdept;
例:
selectseed,account_name,decode(seed,111,1000,200,2000,0)fromt_userInfo//如果seed为111,则取1000;为200,取2000;其它取0
selectseed,account_name,decode(sign(seed-111),1,'bigseed',-1,'littleseed','equalseed')fromt_userInfo//如果seed>111,则显示大;为200,则显示小;其它则显
示相等
13case[实现switch..case逻辑]
SELECTCASEX-FIELD
WHENX-FIELD<40THEN'X-FIELD小于40'
WHENX-FIELD<50THEN'X-FIELD小于50'
WHENX-FIELD<60THEN'X-FIELD小于60'
ELSE'UNBEKNOWN'
END
FROMDUAL
注:CASE语句在处理类似问题就显得非常灵活。当只是需要匹配少量数值时,用Decode更为简洁。
四.数字函数
1,取整函数(ceil向上取整,floor向下取整)
selectceil(66.6)N1,floor(66.6)N2fromdual;
2,取幂(power)和求平方根(sqrt)
selectpower(3,2)N1,sqrt(9)N2fromdual;
3,求余
selectmod(9,5)fromdual;
4,返回固定小数位数(round:四舍五入,trunc:直接截断)
selectround(66.667,2)N1,trunc(66.667,2)N2fromdual;
5,返回值的符号(正数返回为1,负数为-1)
selectsign(-32),sign(293)fromdual;
五.转换函数
1,to_char()[将日期和数字类型转换成字符类型]
1)selectto_char(sysdate)s1,
to_char(sysdate,'yyyy-mm-dd')s2,
to_char(sysdate,'yyyy')s3,
to_char(sysdate,'yyyy-mm-ddhh12:mi:ss')s4,
to_char(sysdate,'hh24:mi:ss')s5,
to_char(sysdate,'DAY')s6
fromdual;
2)selectsal,to_char(sal,'$99999')n1,to_char(sal,'$99,999')n2fromemp
2,to_date()[将字符类型转换为日期类型]
insertintoemp(empno,hiredate)values(8000,to_date('2004-10-10','yyyy-mm-dd'));
3,to_number()转换为数字类型
selectto_number(to_char(sysdate,'hh12'))fromdual;//以数字显示的小时数
六.其他函数
1.user:
返回登录的用户名称
selectuserfromdual;
2.vsize:
返回表达式所需的字节数
selectvsize('HELLO')fromdual;
3.nvl(ex1,ex2):
ex1值为空则返回ex2,否则返回该值本身ex1(常用)
例:如果雇员没有佣金,将显示0,否则显示佣金
selectcomm,nvl(comm,0)fromemp;
4.nullif(ex1,ex2):
值相等返空,否则返回第一个值
例:如果工资和佣金相等,则显示空,否则显示工资
selectnullif(sal,comm),sal,commfromemp;
5.coalesce:
返回列表中第一个非空表达式
selectcomm,sal,coalesce(comm,sal,sal*10)fromemp;
6.nvl2(ex1,ex2,ex3):
如果ex1不为空,显示ex2,否则显示ex3
如:查看有佣金的雇员姓名以及他们的佣金
selectnvl2(comm,ename,')asHaveCommName,commfromemp;
七.分组函数
maxminavgcountsum
1,整个结果集是一个组
1)求部门30的最高工资,最低工资,平均工资,总人数,有工作的人数,工种数量及工资总和
selectmax(ename),max(sal),
min(ename),min(sal),
avg(sal),
count(*),count(job),count(distinct(job)),
sum(sal)fromempwheredeptno=30;
2,带groupby和having的分组
1)按部门分组求最高工资,最低工资,总人数,有工作的人数,工种数量及工资总和
selectdeptno,max(ename),max(sal),
min(ename),min(sal),
avg(sal),
count(*),count(job),count(distinct(job)),
sum(sal)fromempgroupbydeptno;
2)部门30的最高工资,最低工资,总人数,有工作的人数,工种数量及工资总和
selectdeptno,max(ename),max(sal),
min(ename),min(sal),
avg(sal),
count(*),count(job),count(distinct(job)),
sum(sal)fromempgroupbydeptnohavingdeptno=30;
3,stddev返回一组值的标准偏差
selectdeptno,stddev(sal)fromempgroupbydeptno;
variance返回一组值的方差差
selectdeptno,variance(sal)fromempgroupbydeptno;
4,带有rollup和cube操作符的GroupBy
rollup按分组的第一个列进行统计和最后的小计
cube按分组的所有列的进行统计和最后的小计
selectdeptno,job,sum(sal)fromempgroupbydeptno,job;
selectdeptno,job,sum(sal)fromempgroupbyrollup(deptno,job);
cube产生组内所有列的统计和最后的小计
selectdeptno,job,sum(sal)fromempgroupbycube(deptno,job);
八、临时表
只在会话期间或在事务处理期间存在的表.
临时表在插入数据时,动态分配空间
createglobaltemporarytabletemp_dept
(dnonumber,
dnamevarchar2(10))
oncommitdeleterows;
insertintotemp_deptvalues(10,'ABC');
commit;
select*fromtemp_dept;--无数据显示,数据自动清除
oncommitpreserverows:在会话期间表一直可以存在(保留数据)
oncommitdeleterows:事务结束清除数据(在事务结束时自动删除表的数据)