Oracle查询计算当前年龄

时间:2013-07-02 09:39:18

标签: sql oracle

我想在Oracle表中从DOB(出生日期)字段计算当前人的年龄。

DOB字段的数据类型是varchar,日期是以'DD-MON-YY'格式存储的。

当我从10-JAN-49之类的日期计算某个人的当前年龄时,该查询将返回年龄为负数。此外,我观察到如果日期为13至49年,则会给出负面结果。

实施例

22-NOV-83 -valid result
09-FEB-58 --valid result
05-JUN-49 - Invalid result like -36

执行查询以供参考

select round(MONTHS_BETWEEN(sysdate,to_date(dob,'DD-MON-RR'))/12)||' Yrs' 
from birth

感谢任何帮助!

6 个答案:

答案 0 :(得分:5)

/*
A value between 0-49 will return a 20xx year.
A value between 50-99 will return a 19xx year.
*/

来源:http://www.techonthenet.com/oracle/functions/to_date.php

SELECT  FLOOR
        (
            MONTHS_BETWEEN
            (
                SYSDATE
            ,   TO_DATE(SUBSTR(d_date, 1, 7) || '19' || SUBSTR(d_date, -2, 2), 'DD-MON-YYYY')
            ) / 12
        )
FROM
(
        SELECT  '10-JAN-49' d_date FROM DUAL
)

-- The result: 64

答案 1 :(得分:4)

要解决21世纪的问题,只需稍微修改@ the_silk的答案:

SELECT
  CASE WHEN SUBSTR(dob, -2, 2) > 13
  THEN FLOOR
        (
            MONTHS_BETWEEN
            (
                SYSDATE
            ,   TO_DATE(SUBSTR(dob, 1, 7) || '19' || SUBSTR(dob, -2, 2), 'DD-MON-YYYY')
            ) / 12
        )
  ELSE
       FLOOR(MONTHS_BETWEEN(sysdate,TO_DATE(dob,'DD-MON-YY'))/12)
  END
FROM
birth

请注意,虽然这假设'00'和'13'之间的任何日期年份是21世纪,所以这个sql只应该用于构建一次性的一次性脚本,否则它将变得过时并且不久就会失效。

最好的解决方案是重建此表,将varchar列转换为日期列,如Ben提到的那样。

答案 2 :(得分:1)

SELECT MONTHS_BETWEEN( to_date(sysdate,'dd-mm-rr')
                     , to_date(to_date(dob,'yymmdd'),'dd-mm-rr')
                     ) / 12 AS Years 
 FROM birth;

也许这有用。

答案 3 :(得分:1)

我的解决方案是这样的:

SELECT DATE_FORMAT(CURDATE(),'%Y') - DATE_FORMAT(dob,'%Y') as age
FROM `member_master`
having age >=30 and age <=35

答案 4 :(得分:0)

SELECT year, 
       months, 
       Floor(SYSDATE - day_1) AS days 
FROM   (SELECT year, 
               months, 
               Add_months(To_date('30-Oct-1980', 'dd-Mon-yyyy'), 
               12 * year + months) 
                      day_1 
        FROM   (SELECT year, 
                       Floor(Trunc(Months_between(Trunc(SYSDATE), 
                                   To_date('30-Oct-1980', 'dd-Mon-yyyy') 
                                   )) 
                             - year * 12) AS months 
                FROM   (SELECT Floor(Trunc(Months_between(Trunc(SYSDATE), 
                                                   To_date('30-Oct-1980', 
                                                   'dd-Mon-yyyy' 
                                                   ) 
                                                           )) / 
                                                     12) AS year 
                        FROM   dual))); 

答案 5 :(得分:-1)

尝试在TO_DATE的年份部分使用YY

  

RR与YY一样,但两位数字在1950年至2049年间被“舍入”到一年。因此,06被认为是2006而不是1906