1.情景展示
在數據庫中,我們經常需要對日期類型的字段進行操作,下面講一下進行日期計算的三種方式。
2.具體分析
trunc(date[,fmt])
trunc()既可以對日期類型進行截取,也能對數值類型進行截取;
本文只介紹如何對日期進行截取,數值類型的截取方式見文末推薦。
參數說明:
date 待做截取處理的日期
fmt 指定要截取的日期格式。可選項,不帶該參數時,截去時分秒,格式只能分為:一種 y,yy,yyy,yyyy,mm,dd,d;另一種w,iw,ww。
比較常用的是:不帶第二個參數,也就是截取到日。
更多用法舉例:
--參數是日期,不帶第2個參數
SELECT TRUNC(SYSDATE) FROM DUAL;--2017/6/7
--返回當前日期
SELECT TRUNC(SYSDATE, 'DD') FROM DUAL;--2017/6/7
--返回當年第一天
SELECT TRUNC(SYSDATE, 'YYYY') FROM DUAL;--2017/1/1
SELECT TRUNC(SYSDATE, 'YYY') FROM DUAL;--2017/1/1
SELECT TRUNC(SYSDATE, 'YY') FROM DUAL;--2017/1/1
SELECT TRUNC(SYSDATE, 'Y') FROM DUAL;--2017/1/1
--返回當月第一天
SELECT TRUNC(SYSDATE, 'MM') FROM DUAL;--2017/6/1
--返回當前星期的第一天
SELECT TRUNC(SYSDATE, 'D') FROM DUAL;--2017/6/4
--這種方式會報錯
SELECT TRUNC(SYSDATE, 'YYYY-MM-DD') FROM DUAL;
UpdateTime--2017年7月21日11:23:20
格式w,iw,ww區別介紹:
參考鏈接:http://blog.chinaunix.net/uid-23072872-id-3664151.html
這3個參數均為取每周第一天,區別如下:
w,按每月的1日為每周第一天,例如1日為當月第一周第一天,8日為第二周第一天……依此類推;
ww,與w功能類似,不過它是按每年的1月1日為第一周第一天,1月8日為第二周第一天……依此類推;
iw,不受月份與年份的影響,直接取日期參數的周一。
舉例:
--trunc(sysdate),截取當前日期年月日
--trunc(sysdate,'iw')取當前日期所在星期的星期一
--trunc(sysdate,'ww') 按年度計算取當前日期所在星期的星期一
--trunc(sysdate,'w') 按月度計算取當前日期所在星期的星期一
SELECT trunc(sysdate) 當前日期,trunc(sysdate,'iw') 取星期一,trunc(sysdate,'ww') 按年度計算取星期一,trunc(sysdate,'w') 按月度計算取星期一 FROM DUAL
extract()
extract()函數定義如下:
extract (
{ year | month | day | hour | minute | second }
| { timezone_hour | timezone_minute }
| { timezone_region | timezone_abbr }
from { date_value | interval_value } )
從日期類型當中提取年、月、日
select extract( year from sysdate) FROM DUAL
union
select extract( month from sysdate) FROM DUAL
union
select extract( day from sysdate) FROM DUAL
返回的是數值類型。
從日期字符串當中提取年、月、日
需要加date關鍵字,將日期字符串轉成日期類型
select extract( year from date '2022-03-08') FROM DUAL
union
select extract( month from date '2022-03-08') FROM DUAL
union
select extract( day from date '2022-03-08') FROM DUAL
從timestamp中獲取年月日時分秒
select
extract(year from systimestamp) year
,extract(month from systimestamp) month
,extract(day from systimestamp) day
,extract(minute from systimestamp) minute
,extract(second from systimestamp) second
,extract(timezone_hour from systimestamp) th
,extract(timezone_minute from systimestamp) tm
,extract(timezone_region from systimestamp) tr
,extract(timezone_abbr from systimestamp) ta
from dual
interval
interval '{ integer | integer time_expr | time_expr }'
{ { day | hour | minute } [ ( leading_precision ) ]
| second [ ( leading_precision [, fractional_seconds_precision ] ) ] }
[ to { day | hour | minute | second [ (fractional_seconds_precision) ] } ]
leading_precision值的范圍是0到9, 默認是2,表示精確到第幾位;
舉個栗子:
由上面,我們知道,間隔可以用:day、hour、minute等代表時間的關鍵詞,並且最大間隔的默認最大支持2位。
那如果,我們強行使用查過2位數的間隔數呢?
意思是說:默認要求的是最多兩位,你卻用了3位數。
怎么辦?
我們需要手動調高要支持的位數。
time_expr的格式為:hh[:mi[:ss[.n]]] or mi[:ss[.n]] or ss[.n], n表示微秒。
范圍值:
hour: 0 to 23
minute: 0 to 59
second: 0 to 59.999999999
間隔1年、1月
--間隔1年
SELECT interval '1' year FROM DUAL
union
--間隔1月
SELECT interval '1' month FROM DUAL
--間隔1天
SELECT interval '1' day FROM DUAL
union
--間隔1天零1小時
SELECT interval '1 1' day to hour FROM DUAL
union
--間隔1天零1小時零1分
SELECT interval '1 1:1' day to minute FROM DUAL
--間隔1天零1小時零1分零1秒
SELECT interval '1 1:1:1' day to second FROM DUAL
我們可以看到:
秒后面的單位是微妙,最大支持6位數,如果超的話,會進行四舍五入。
second(2,6)表示的含義是:秒保留2位,微妙保留6位,微妙超過6位的部分按照四舍五入處理,如果不足6位的話,自動補零。
2022年4月19日19:35:15
關於trunc()的妙用
我們可以根據出生日期到系統當前時間,計算出間隔月數,並除以12取整就可以計算出年齡。
TRUNC( months_between( SYSDATE, p.BIRTH_DAY ) / 12 ) AS AGE
寫在最后
哪位大佬如若發現文章存在紕漏之處或需要補充更多內容,歡迎留言!!!