Первым шагом является интерпретация двузначного года.Вы не получаете это из коробки.Oracle знает форматы YY и RR, но, например, 48 - это 2048 для них обоих, а вы хотите, чтобы это было 1948.
Текущий возраст тоже немного сложен.В этом разница между датой рождения и сегодняшним днем в годах минус один год, если день еще не достигнут.
И месяцы - это всегда что-то странное для вычисления, потому что они не имеют фиксированной длины.Следовательно, мы должны жить с приблизительными значениями.
with proper as
(
select
fnamn,
enamn,
case when to_date(substr(pnr, 1, 6), 'yymmdd') >= trunc(sysdate)
then to_date(substr(pnr, 1, 6), 'yymmdd') - interval '100' year(3)
else to_date(substr(pnr, 1, 6), 'yymmdd')
end as birthdate
from bilägare
)
select
fnamn,
enamn,
birthdate,
extract(year from sysdate) - extract(year from birthdate)
- case when to_char(sysdate, 'mmdd') < to_char(birthdate, 'mmdd')
then 1 else 0
end as age,
round(months_between(sysdate, birthdate)) as months
from proper;
Rextester demo: http://rextester.com/OHY39782
ОБНОВЛЕНИЕ: Как уже упоминалось, рассчитывать с месяцами всегда неточно.Однако MONTH_BETWEEN
дает десятичное число разницы месяцев.Вы можете использовать это и просто разделить на 12. Я предполагаю, что здесь и там могут быть небольшие просчеты.Играйте с TRUNC
и ROUND
или даже CASE WHEN
, пока не будете удовлетворены результатами.
trunc(months_between (sysdate, birthdate) / 12) as age_years
trunc(mod(months_between (sysdate, birthdate), 12)) as age_months