Việc giải thích năm có hai chữ số và thế kỷ ngụ ý của nó dường như dựa trên cả giá trị của nó và mã PIN. Các phạm vi cho sự trùng lặp đó, nhưng sau đó cả năm bị hạn chế; vì vậy, có vẻ như bạn có thể sử dụng một biểu thức chữ hoa để kiểm tra cả hai:
-- 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;
mà đối với dữ liệu đó, dựa trên hai ví dụ của bạn và các phạm vi liên quan, đưa ra:
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
Trường hợp chọn giá trị thế kỷ hai chữ số dựa trên mã PIN và sau đó - vì chúng trùng nhau - phạm vi năm có hai chữ số.
Nếu thiết kế dữ liệu thay đổi khiến các phần chồng chéo không còn duy nhất dựa trên năm có hai chữ số, bạn còn gặp phải vấn đề khác. Sẽ rất thú vị khi xem điều gì sẽ xảy ra khi chúng ta đến năm 2040 ...
Và nếu bạn có SSN không khớp với các phạm vi bạn đã hiển thị, hãy nói 12105050000
(với mã PIN 500, nhưng năm có hai chữ số không nằm trong phạm vi 00-39 hoặc 54-99) thì biểu thức chữ hoa chữ thường sẽ trả về giá trị rỗng và năm có hai chữ số sau đó sẽ được hiểu là 0050. Thay vào đó, bạn có thể mắc lỗi bằng cách thay đổi mô hình định dạng - phụ thuộc nếu nó có thể xảy ra và cách bạn muốn xử lý nó nếu nó xảy ra.
Dù sao thì bạn cũng có thể hiểu được điều này, nhưng để xử lý kịch bản ngày + 40 được đề cập trong nhận xét, bạn có thể sử dụng một biểu thức chữ hoa chữ thường khác để điều chỉnh số ngày:
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
...