Запрос 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
Любая помощь ценится!
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