因此为我提供了一个表格,其中包含出生日期为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;
答案 0 :(得分:1)
第一步是解释两位数的年份。您无需开箱即用。 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;
上个月的演示: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
答案 1 :(得分:0)
请纠正我的理解,我将修改查询
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 |
+--------+------+--------+------+-------+
答案 2 :(得分:0)
这将起作用:
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