Использование оператора «Между» после «THEN» в операторе «CASE» в «WHERE» - PullRequest
0 голосов
/ 29 июня 2018

Я пытаюсь сделать что-то подобное

select *
from m
where CASE WHEN x=1 THEN trunc(m.ATT_DATE) between '18-01-01' AND '18-12-31'
WHEN x=2 THEN trunc(m.main_date) between '18-01-01' AND '18-12-31'
ELSE 1 END = 1;

х является переменной

Я получаю эту ошибку ORA-00905: мот-кли отсутствует 00905. 00000 - «пропущенное ключевое слово» * Причина:
* Действие: Erreur à la ligne 182, колонна 42

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

Вы не можете поместить логику в результат дела таким образом, и если бы вы могли, вы бы получили логический результат, смешанный с числовым результатом.

В зависимости от того, что вы хотите сделать, если x не равно ни 1, ни 2, вы можете либо ничего не вернуть в этой ситуации с одним из них:

select *
from m
where (x=1 and trunc(m.att_date) between date '2018-01-01' and date '2018-12-31')
  or (x=2 and trunc(m.main_date) between date '2018-01-01' and date '2018-12-31');

select *
from m
where (x=1 and m.att_date >= date '2018-01-01' and m.att_date < date '2019-01-01')
  or (x=2 and m.main_date >= date '2018-01-01' and m.main_date < date '2019-01-01');

select *
from m
where case when x=1 then m.att_date when x=2 then m.main_date end >= date '2018-01-01'
  and case when x=1 then m.att_date when x=2 then m.main_date end < date '2019-01-01';

, где последние два сравниваются с полным диапазоном даты / времени вместо использования trunc(), что предотвратит использование индексов для этих столбцов; или если вы хотите включить все строки, когда x не равно 1 или 2:

select *
from m
where (x=1 and trunc(m.att_date) between date '2018-01-01' and date '2018-12-31')
  or (x=2 and trunc(m.main_date) between date '2018-01-01' and date '2018-12-31')
  or x not in (1,2);

select *
from m
where (x=1 and m.att_date >= date '2018-01-01' and m.att_date < date '2019-01-01')
  or (x=2 and m.main_date >= date '2018-01-01' and m.main_date < date '2019-01-01')
  or x not in (1,2);

select *
from m
where case when x=1 then m.att_date when x=2 then m.main_date
    else date '2018-01-01' end >= date '2018-01-01'
  and case when x=1 then m.att_date when x=2 then m.main_date
    else date '2018-01-01' end < date '2019-01-01';

Первые два добавляют явные проверки для x (и первое, что делает @Gordon ...); третий использует case .. else .. для предоставления значения по умолчанию, которое находится в диапазоне, что, вероятно, в конечном итоге будет выполнять больше работы, чем действительно необходимо.

Лично я бы использовал средний в каждом случае.

0 голосов
/ 29 июня 2018

Я бы написал так:

select m.*
from m
where (x = 1 and trunc(m.ATT_DATE) between date '2018-01-01' and date '2018-12-31') or
      (x = 2 and trunc(m.main_date) between date '2018-01-01' and date '2018-12-31') or
      (x not in (1, 2));

Примечания:

  • Обычно выражения case можно заменить простой логической логикой в ​​предложении where.
  • Одна из проблем вашего запроса заключается в том, что Oracle не распознает логические значения, поэтому предложение then не может возвращать логическое выражение.
  • Константы даты следует вводить с ключевыми словами date.
  • Константы даты должны использовать стандартный формат ANSI / ISO, например, ГГГГ-ММ-ДД.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...