Проверка первых 6 цифр в SQL-запросе в Oracle SQL developer

#sql #oracle

#sql #Oracle

Вопрос:

Существует требование, при котором мне нужно подтвердить номер удостоверения личности с первыми 6 цифрами в качестве DOB. Мне нужно выяснить, что пользователи не поддерживают правильный формат. Если dob равен 02/10/1983 — 83021023456 amp;amp;, если 02/10/2083 -> 83221023456 (DOB указан в ММ / ДД / ГГГГ, и если год рождения> 2000, то 20 добавляется к месяцу dob). Запрос, с которым я пытался, приведен ниже:-

  SELECT f_account_name,F_SSN ,F_DOB  from table  where  
   CASE WHEN SUBSTR(to_char(F_DOB, 'YYYY-MM-DD'),0,4)>2000
   THEN
      SUBSTR(f_ssn,0,6) <>
      SUBSTR(to_char(F_DOB, 'YY-MM-DD'),0,2)
      ||SUBSTR(to_char(F_DOB, 'YY-MM-DD'),4,2)
      ||SUBSTR(to_char(F_DOB, 'YY-MM-DD'),7,2) 
    ELSE 
       SUBSTR(f_ssn,0,6) <>
        SUBSTR(to_char(F_DOB, 'YY-MM-DD'),0,2)
      ||(SUBSTR(to_char(F_DOB, 'YY-MM-DD'),4,2) 20)
      ||SUBSTR(to_char(F_DOB, 'YY-MM-DD'),7,2) 
      END;
  

Не работает.

Ответ №1:

У вас не может быть сравнения внутри CASE выражения; поскольку левая часть выражения идентична, его просто переместить, а затем вы можете упростить остальное:

 SELECT f_account_name,
       F_SSN,
       F_DOB
FROM   table_name
WHERE  SUBSTR(f_ssn,0,6) !=
         CASE
         WHEN EXTRACT( YEAR FROM F_DOB ) > 2000
         THEN TO_CHAR( F_DOB, 'YYMMDD')
         ELSE TO_CHAR( F_DOB, 'YY' )
              || TO_CHAR( EXTRACT( MONTH FROM F_DOB ) 20, 'FM00' )
              || TO_CHAR( F_DOB, 'DD') 
         END;
  

или, если правило заключается в добавлении 20 к месяцу за каждое столетие после 1900 года (т.Е. 20XX добавить 20 и 21XX добавить 40 и т.д.), То:

 SELECT f_account_name,
       F_SSN,
       F_DOB
FROM   table_name
WHERE  SUBSTR(f_ssn,0,6) != 
         TO_CHAR( F_DOB, 'YY' )
         || TO_CHAR(
              EXTRACT( MONTH FROM F_DOB )
                20 * GREATEST( TRUNC( EXTRACT( YEAR FROM F_DOB ) / 100 ) - 19, 0 ),
              'FM00'
            )
         || TO_CHAR( F_DOB, 'DD');
  

Ответ №2:

Я попробовал некоторую арифметику даты и работал с числами, а не со строками …

 WITH
-- your input
indata(f_account_name,f_ssn,f_dob) AS (
                   --string -- number    -- string
            SELECT 'Arthur',83021023456,'02/10/1983' FROM dual
  UNION ALL SELECT 'Tricia',83221023456,'02/10/2083' FROM dual
) 
SELECT 
  f_account_name
, f_ssn
, f_dob
FROM indata
WHERE CAST(TRUNC(f_ssn/100000) AS NUMBER(6)) 
    -- ^ integer division by 100000 to get the first 6 digits ...
    =   MOD(EXTRACT(YEAR FROM TO_DATE(f_dob,'MM/DD/YYYY')),100) * 10000
    -- ^ modulo year of date of 100 gives 3rd and 4th digit of year
        (
          EXTRACT(MONTH FROM TO_DATE(f_dob,'MM/DD/YYYY'))
          CASE 
            WHEN EXTRACT(YEAR FROM TO_DATE(f_dob,'MM/DD/YYYY')) >= 2000 THEN 20
            ELSE 0 
          END 
        ) * 100
        EXTRACT(DAY FROM TO_DATE(f_dob,'MM/DD/YYYY'))
 ;