Случай Oracle SQL с условием

#sql #oracle #oracle8i

#sql #Oracle #oracle8i

Вопрос:

У меня есть вопрос относительно заявления Oracle SQL case.

в условии where я хотел бы применить следующее условие. если salary_date равно null, то effective_date должно быть больше 01-Jan-2016

Я попробовал как

 case when salary_date is null then
trunc(effective_date) >= '01-JAN-2016' else
         null end
  

Однако вышеприведенное привело к

ORA-00933: команда SQL не завершена должным образом

Как я могу это решить?

Комментарии:

1. Не связано, но: не полагайтесь на злое неявное преобразование типов данных. '01-JAN-2016' является строковым значением, а не a DATE . Используйте правильный литерал даты, например DATE '2016-01-01' , или to_date('2016-01-01', 'yyyy-mm-dd')

Ответ №1:

Проблема с вашим кодом заключается в том, что интерпретатор SQL ожидает увидеть значение после ключевого слова ‘then’, тогда как у вас есть условие.

Попробуйте что-то вроде этого, может быть:

 case when salary_date is null and trunc(effective_date) >= '01-JAN-2016' 
     then <value you need> 
     else null
  

Комментарии:

1. Спасибо за понимание. Я должен проверять только тогда, когда salary_date равно нулю, тогда effective_date должно быть больше ’01-JAN-2016′

2. @user75ponic: это именно то, что делает это условие.

3. @a_horse_with_no_name — не совсем. Если вы прочтете вопрос OP полностью, а не только фрагмент кода, вы увидите, что он пытался использовать регистр «условие» в предложении WHERE. Увы, в Oracle SQL есть только выражения case, поэтому «case» изначально был неправильным инструментом. Что-то подобное будет работать в PL / SQL, но не в обычном SQL. massive_dynamic показывает пример (правильного) использования выражений case, но это не связано с проблемой OP.

Ответ №2:

Вы можете попробовать это без указания регистра

 SELECT
..
..
WHERE ( trunc(effective_date) >= '01-JAN-2016' AND salary_date is null ) 
OR ( <some other condition> )
  

Комментарии:

1. Спасибо за понимание. Я должен проверять только тогда, когда salary_date равно нулю, тогда effective_date должно быть больше ’01-JAN-2016′

2. это то, что делает условие AND внутри круглых скобок .. попробуйте код и проверьте результат

3. trunc(effective_date) >= '01-JAN-2016' условие будет проверяться только тогда, когда salarydate равно null из-за И

4. @mhasan — Операция правильная. Логика очень проста: ЕСЛИ salary_date равно null, ТО eff_date > что угодно. ЕСЛИ a, ТО b может быть записан как «НЕ a ИЛИ b». Вы написали это как » a И b «. Вы ошиблись в двух вещах.

Ответ №3:

 ...where salary_date is not null or effective_date >= date '2016-01-01'
  

Поскольку Oracle SQL не имеет «IF… ЗАТЕМ» используйте базовую логику для преобразования вашего логического выражения. ЕСЛИ a, ТО b — это то же самое, что и (НЕ a) ИЛИ b. Это то, что я сделал выше.

НЕ … НЕ … сравнивать даты со строками. '01-JAN-2016' является строкой, а не датой. Вы ДОЛЖНЫ преобразовать его в дату, например, с to_date('01-JAN-2016', 'dd-MON-yyyy') помощью .

Или, в качестве альтернативы, обратите внимание, как я ввожу «литерал даты» (фиксированную дату). Если мне не нужно вводить время суток, я могу использовать выражение date '2016-01-01' , которое является стандартным SQL (ANSI) «литералом даты». Тогда вам не нужно указывать модель формата даты; она ВСЕГДА ДОЛЖНА быть в точном формате гггг-мм-дд.

Комментарии:

1. Кто бы ни проголосовал против, не могли бы вы оставить записку, объясняющую ваше возражение против моего ответа? Спасибо!