SQL, дата рождения до текущего возраста - PullRequest
0 голосов
/ 04 октября 2018

Итак, мне дали таблицу, содержащую данные с датами рождения, например, 540401-4428 (гггммдд - последние четыре числа (персональный идентификационный номер)* и сколько месяцев . На данный момент PNR просто печатает целое число.

fnamn=firstname
enamn=lastname
PNR = date of birth

Предположительно, будет выглядеть примерно так:

Maria, Stjärnkvist, 33,5 år.
Leyla, Errstraid, 42,2 år.
Arne, Möller, 76,6 år.

Вот как далеко я прошел:

declare 
cursor c_användare 
is select UPPER(SUBSTR(fnamn,1,1)) || SUBSTR(fnamn,2),Upper(substr(Enamn,1,1))
|| substr(enamn,2) , PNR
from bilägare; 
v_fnamn bilägare.fnamn%type; 
v_enamn bilägare.enamn%type; 
v_pnr bilägare.pnr%type; 

begin 
if not c_användare%isopen then 
open c_användare; 
end if; 
loop 
fetch c_användare 
into v_fnamn,v_enamn,v_pnr; 
exit when c_användare%notfound; 
dbms_output.put_line(v_Fnamn||', '||v_Enamn||', '||v_pnr||'år'); 
 end loop; 
 close c_användare; 
end;

Ответы [ 3 ]

0 голосов
/ 04 октября 2018

Первым шагом является интерпретация двузначного года.Вы не получаете это из коробки.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
0 голосов
/ 05 октября 2018

это будет работать:

select floor(to_number(sysdate- 
to_date('19'||substr('540401',1,instr('540401-4428',' - 
')-1),'YYYYMMDD'))/365)||'years' as years
,floor(((to_number(sysdate-to_date('19'||substr('540401',1,instr('540401- 
4428','-')-1),'YYYYMMDD'))/365)-
floor((to_number(sysdate-to_date('19'||substr('540401',1,instr('540401- 
4428','-')-1),'YYYYMMDD'))/365)))*10)*1.2||'months' as months
from dual;

вывод:

64years 6months
0 голосов
/ 04 октября 2018

Пожалуйста, исправьте мое понимание, я изменю запрос

WITH
    tab_data
    AS
        (SELECT 'Maria' name, '540401-4428' pnr FROM DUAL
         UNION ALL
         SELECT 'Gaurav' name, '600802-1234' pnr FROM DUAL
         UNION ALL
         SELECT 'Rohan' name, '881011-9898' pnr FROM DUAL)
SELECT name,
       REGEXP_SUBSTR (pnr,
                      '[^-]+',
                      1,
                      2)
           id,
       REGEXP_SUBSTR (pnr,
                      '[^-]+',
                      1,
                      1)
           dob,
       TRUNC (  MONTHS_BETWEEN (SYSDATE,
                                TO_DATE (REGEXP_SUBSTR (pnr,
                                                        '[^-]+',
                                                        1,
                                                        1),
                                         'RRMMDD'))
              / 12)
           year,
       TRUNC (MOD (MONTHS_BETWEEN (SYSDATE,
                                   TO_DATE (REGEXP_SUBSTR (pnr,
                                                           '[^-]+',
                                                           1,
                                                           1),
                                            'RRMMDD')),
                   12))
           months
  FROM tab_data;

Результат:

+--------+------+--------+------+-------+
|  NAME  |  ID  |  DOB   | YEAR | MONTH |
+--------+------+--------+------+-------+
| Maria  | 4428 | 540401 |   64 |     6 |
| Guarav | 1234 | 600802 |   58 |     2 |
| Rohan  | 9898 | 881011 |   29 |    11 |
+--------+------+--------+------+-------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...