用month_between做,應該會好一些。
站在用戶的角度思考問題,與客戶深入溝通,找到施秉網站設計與施秉網站推廣的解決方案,憑借多年的經驗,讓設計與互聯網技術結合,創造個性化、用戶體驗好的作品,建站類型包括:網站建設、網站設計、企業官網、英文網站、手機端網站、網站推廣、主機域名、網頁空間、企業郵箱。業務覆蓋施秉地區。
select
當前日期,
出生日期,
trunc(months_between(當前日期,出生日期)/12) 年數,
trunc(months_between(當前日期,出生日期))%12 月數,
ceil(當前日期-add_month(出生日期,trunc(months_between(當前日期,出生日期))) 天數 from table
可能一些細微的地方還需要些調整,不過大體上應該差不多了。
最后那個ceil可能要分成兩個case when的部分是
case when substr(to_char(當前日期,'yyyy-mm-dd'),-5) != substr(to_char(出生日期,'yyyy-mm-dd'),-5) then trunc(當前日期-add_month(出生日期,trunc(months_between(當前日期,出生日期)))
when substr(to_char(當前日期,'yyyy-mm-dd'),-5) = substr(to_char(出生日期,'yyyy-mm-dd'),-5) then 1 end 天數
我看了下你上面的兩個例子,好像因為日期相等比較特殊,所以我嘗試用ceil試試,如果不行那么就用下面這個,我估計差不多了,不過我可沒有環境,只能是憑空想象,剩下的只能你自己去實驗和修改了。
SQL語句如下:
select?floor(MONTHS_BETWEEN(sysdate,date'2016-1-1')/12)?as?age?from?dual;
結果:
select floor(months_between(to_date(concat(extract(year from sysdate),'-10-31'),'YYYY-MM-DD'),to_date(生日的日期,'yyyy-mm-dd'))/12) from table_name
floor 向下取整
months_between 日期相差的月份數
concat字字符串連接
extract(year from sysdate) 返回當前日期的年份
這個辦法很多,如果是比較精確的可以用month_between函數,然后除以12,最后在trunc這樣就能得到具體的年齡了。
比如trunc(month_between(sysdate,時間類型的生日字段)/12)
個人感覺這個精確一些,能精確到天,只要還沒過生日,那么就不會加一歲。
當然二者直接相減trunc((sysdate-時間類型的生日字段)/365)也可以。
sysdate-時間類型的生日字段,這么相減默認出現的是相差的天數,所以除以365。這個也可以,不過有些年是366天,不過因為366天的年分比較少,所以基本上不會相差很多。只是會出現,“提前”的情況。不過80年最多才21天(大概是這樣,我沒細算,就算四年一次),所以對實際影響不是特別大。如果要求準確那么還是上面的靠譜一些。
用函數取出字段年,然后用現在的年相減也可以。這個就是一個大概(個人認為更加不靠譜),比如一個人2050年12月30日出生,現在是2055年后的1月1號,那么按照年來說就是5,但是其實才4歲多一點,所以年這個只是一個大概的,不會十分準確。
可用to_char函數將date類型轉成字符類型。
如emp表中有如下數據:
如果計算生日的方法是當前日期的年份減去生日的年份,可用如下語句:
select?ename,hiredate,to_char(sysdate,'yyyy')-to_char(hiredate,'yyyy')?from?emp;
查詢結果:
CREATE??TABLE??test?(
id??varchar2(10),
date_of_birth??date
);
INSERT?INTO?test?VALUES('05576767',??TO_DATE('1957-3-28',??'YYYY-MM-DD'));
INSERT?INTO?test?VALUES('05563743',??TO_DATE('2013-3-27',??'YYYY-MM-DD'));
INSERT?INTO?test?VALUES('05563744',??TO_DATE('2013-7-15',??'YYYY-MM-DD'));
INSERT?INTO?test?VALUES('05563745',??TO_DATE('2013-6-7',???'YYYY-MM-DD'));
INSERT?INTO?test?VALUES('05563741',??TO_DATE('2010-11-21',?'YYYY-MM-DD'));
SELECT
id,
CASE?WHEN??MONTHS_BETWEEN(TRUNC(SYSDATE),?date_of_birth)?*?1.0?/?12??1?THEN??ROUND(MONTHS_BETWEEN(TRUNC(SYSDATE),?date_of_birth)?*?1.0?/?12,?1)
WHEN??MONTHS_BETWEEN(TRUNC(SYSDATE),?date_of_birth)??1?THEN??ROUND(MONTHS_BETWEEN(TRUNC(SYSDATE),?date_of_birth),?1)
???ELSE??TRUNC(sysdate)?-?date_of_birth?
END??AS??age,
CASE?WHEN??MONTHS_BETWEEN(TRUNC(SYSDATE),?date_of_birth)?*?1.0?/?12??1?THEN??'歲'
WHEN??MONTHS_BETWEEN(TRUNC(SYSDATE),?date_of_birth)??1?THEN???'月'
???ELSE??'天'
END??AS??Unit
FROM
test;
ID??????????????????????????AGE?UNIT
--------------------?----------?------
05576767???????????????????56.3?歲
05563743????????????????????3.6?月
05563744??????????????????????1?天
05563745????????????????????1.3?月
05563741????????????????????2.7?歲