#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'))
;