簡體   English   中英

SQL,出生日期到當前年齡

[英]SQL, Date of birth to current age

所以我得到了一個包含生日數據的表格,如 540401-4428(yymmdd - 最后四個數字(個人身份號碼)我試圖弄清楚我應該如何使用該數字來計算當前年齡和多少個月。此刻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;

第一步是解釋兩位數的年份。 你沒有得到這個開箱即用的。 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;

Reextester 演示: http ://rextester.com/OHY39782

更新:如前所述,以月計算總是不精確的。 但是, MONTH_BETWEEN為您提供月份差異的十進制數。 您可能想使用它並簡單地除以 12。我想這里和那里可能會有輕微的計算錯誤。 使用TRUNCROUND甚至CASE WHEN ,直到您對結果感到滿意為止。

trunc(months_between (sysdate, birthdate) / 12) as age_years
trunc(mod(months_between (sysdate, birthdate), 12)) as age_months

請糾正我的理解,我將修改查詢

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 |
+--------+------+--------+------+-------+

這將起作用:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM