Norwegian identification number 比您建议的要复杂,正如 in this question 所提到的。您可以从中调整答案;使用 CTE 在该答案上生成相同的虚拟数据加上几个 D 数字(并且没有无用的未来日期值):
with t42 (ssn) as (
select '12104900000' from dual
union all select '12105099999' from dual
union all select '01010000001' from dual
union all select '02029949902' from dual
union all select '03035450003' from dual
union all select '04049974904' from dual
union all select '05050050005' from dual
union all select '07074090007' from dual
union all select '08089999908' from dual
union all select '01121799908' from dual
union all select '48089999908' from dual
union all select '52104900000' from dual
)
select ssn
from t42
where months_between(trunc(sysdate), to_date(
case
when to_number(substr(ssn, 1, 2)) > 31
then to_char(to_number(substr(ssn, 1, 2)) - 40, 'FM00')
else substr(ssn, 1, 2)
end
|| substr(ssn, 3, 2)
|| case
when to_number(substr(ssn, 7, 3)) between 0 and 499
and to_number(substr(ssn, 5, 2)) between 0 and 99 then '19'
when to_number(substr(ssn, 7, 3)) between 500 and 749
and to_number(substr(ssn, 5, 2)) between 54 and 99 then '18'
when to_number(substr(ssn, 7, 3)) between 500 and 999
and to_number(substr(ssn, 5, 2)) between 0 and 39 then '20'
when to_number(substr(ssn, 7, 3)) between 900 and 999
and to_number(substr(ssn, 5, 2)) between 40 and 99 then '19'
end
|| substr(ssn, 5, 2), 'DDMMYYYY')
) < 360;
返回 12 个虚拟值中的 5 个:
SSN
-----------
02029949902
05050050005
08089999908
01121799908
48089999908
或者使用转换后的日期和年龄:
with ...
select ssn, to_char(dob, 'YYYY-MM-DD') as dob,
trunc(months_between(trunc(sysdate), dob)) as age_in_months,
trunc(months_between(trunc(sysdate), dob)/12) as age_in_years
from (
select ssn,
to_date(
case
when to_number(substr(ssn, 1, 2)) > 31
then to_char(to_number(substr(ssn, 1, 2)) - 40, 'FM00')
else substr(ssn, 1, 2)
end
|| substr(ssn, 3, 2)
|| case
when to_number(substr(ssn, 7, 3)) between 0 and 499
and to_number(substr(ssn, 5, 2)) between 0 and 99 then '19'
when to_number(substr(ssn, 7, 3)) between 500 and 749
and to_number(substr(ssn, 5, 2)) between 54 and 99 then '18'
when to_number(substr(ssn, 7, 3)) between 500 and 999
and to_number(substr(ssn, 5, 2)) between 0 and 39 then '20'
when to_number(substr(ssn, 7, 3)) between 900 and 999
and to_number(substr(ssn, 5, 2)) between 40 and 99 then '19'
end
|| substr(ssn, 5, 2), 'DDMMYYYY') as dob
from t42
)
where months_between(trunc(sysdate), dob) < 360;
SSN DOB AGE_IN_MONTHS AGE_IN_YEARS
----------- ---------- ------------- ------------
02029949902 1999-02-02 227 18
05050050005 2000-05-05 212 17
08089999908 1999-08-08 221 18
01121799908 2017-12-01 1 0
48089999908 1999-08-08 221 18