Penafsiran tahun dua digit dan abad tersirat tampaknya didasarkan pada nilai dan PIN. Rentang untuk itu tumpang tindih, tetapi setahun penuh kemudian dibatasi; jadi sepertinya Anda dapat menggunakan ekspresi huruf besar/kecil yang memeriksa keduanya:
-- CTE for dummy data
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 '06063999906' from dual
union all select '07074090007' from dual
union all select '08089999908' from dual
)
select ssn, to_date(substr(ssn, 1, 4)
|| 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;
yang untuk data tersebut, berdasarkan dua contoh Anda dan rentang yang terlibat, memberikan:
SSN DOB
----------- ----------
12104900000 1949-10-12
12105099999 1950-10-12
01010000001 1900-01-01
02029949902 1999-02-02
03035450003 1854-03-03
04049974904 1899-04-04
05050050005 2000-05-05
06063999906 2039-06-06
07074090007 1940-07-07
08089999908 1999-08-08
Kasing mengambil nilai abad dua digit berdasarkan PIN dan kemudian - karena tumpang tindih - rentang tahun dua digit.
Jika desain data berubah sehingga tumpang tindih tidak lagi unik berdasarkan tahun dua digit, Anda memiliki masalah lebih lanjut. Akan menarik untuk melihat apa yang terjadi ketika kita mencapai tahun 2040...
Dan jika Anda memiliki SSN yang tidak cocok dengan rentang yang Anda tunjukkan, ucapkan 12105050000
(dengan PIN 500, tetapi tahun dua digit tidak dalam kisaran 00-39 atau 54-99) maka ekspresi huruf besar akan kembali nol dan tahun dua digit kemudian akan ditafsirkan sebagai 0050. Anda dapat membuat kesalahan sebagai gantinya dengan mengubah model format - tergantung apakah itu bisa terjadi dan bagaimana Anda ingin menanganinya jika itu terjadi.
Anda mungkin dapat mengetahui hal ini, tetapi untuk menangani skenario hari+40 yang disebutkan dalam komentar, Anda dapat menggunakan ekspresi kasus lain untuk menyesuaikan nomor hari:
select ssn, to_date(
case
when substr(ssn, 1, 2) > 31 then to_char(to_number(substr(ssn, 1, 2)) - 40, 'FM99')
else substr(ssn, 1, 2)
end
|| substr(ssn, 3, 2)
|| case
when to_number(substr(ssn, 7, 3)) between 0 and 499
...