sql >> データベース >  >> RDS >> Oracle

00-49 生まれの場合、DDMMYY を DDMMYYYY に変換する

    2 桁の年とその暗黙の世紀の解釈は、その値と PIN の両方に基づいているようです。その範囲は重複しますが、通年は制限されます。したがって、両方をチェックするケース式を使用できるようです:

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

    そのデータについて、2 つの例と関連する範囲に基づいて、次のようになります。

    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
    

    このケースでは、PIN に基づいて 2 桁の世紀の値が選択され、次に (これらが重複しているため) 2 桁の年の範囲が選択されます。

    重複が 2 桁の年に基づいて一意でなくなるようにデータ設計が変更された場合、さらに問題が発生します。 2040 年に到達したときに何が起こるかを見るのは興味深いことです...

    表示された範囲と一致しない SSN がある場合は、12105050000 と言ってください。 (PIN 500 を使用するが、2 桁の年が 00 から 39 または 54 から 99 の範囲ではない)、case 式は null を返し、2 桁の年は 0050 として解釈されます。フォーマット モデル - 発生する可能性があるかどうか、および発生した場合にどのように処理するかによって異なります。

    とにかくこのビットを理解することはできますが、コメントで言及されている day+40 シナリオを処理するには、別のケース式を使用して日付番号を調整できます。

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



    1. 最初のレベルのカテゴリを1回だけ表示するにはどうすればよいですか?

    2. SQL Server での非常に大きなテーブルの UPDATE または MERGE

    3. 本番用のSQLExpress?

    4. Oracle SQLエラー:インデックスにINまたはOUTパラメータがありません::1