Запрос Oracle для вычисления текущего возраста



Я хочу вычислить текущий возраст человека из поля DOB (дата рождения)в таблице Oracle.



Тип данных поля DOB-varchar, а дата is хранится в формате '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


Любая помощь ценится!

514   6  

6 ответов:

Чтобы обойти проблему 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 в столбец даты, как на это намекал Бен.

/*
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
SELECT MONTHS_BETWEEN( to_date(sysdate,'dd-mm-rr')
                     , to_date(to_date(dob,'yymmdd'),'dd-mm-rr')
                     ) / 12 AS Years 
 FROM birth;

Может быть, это сработает.

Мое решение было бы примерно таким:

SELECT DATE_FORMAT(CURDATE(),'%Y') - DATE_FORMAT(dob,'%Y') as age
FROM `member_master`
having age >=30 and age <=35
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))); 

Попробуйте использовать YY в части Year вашего TO_DATE

RR как YY, но две цифры `округлены" до года в диапазоне от 1950 до 2049. Таким образом, 06 считается 2006 вместо 1906

Comments

    Ничего не найдено.