Вернуть min(DATE), если Date не существует

В Oracle SQLDeveloper я пытаюсь выполнить запрос, в котором я возвращаю определенную дату в качестве StartDate, но возвращаю минимальную дату, если самая ранняя существующая дата больше указанной даты начала. Я попытался сделать это с помощью оператора CASE, но все время получаю сообщение об ошибке «отсутствуют правые скобки». Вот мой код до сих пор:

select 
  a.program
  , a.match_file
  , (case when b.date = '27-JAN-13' then b.date else min(b.date end)) as Startdate
from Schema1.program a, Schema1.detail b
where a.match_file = b.matchfile
  and (case when b.date=' ' then min(b.date) else b.date end) = '27-JAN-13'
  group by a.program, a.match_file
;

Может кто-нибудь, пожалуйста, дайте мне знать, если я делаю это неправильно? Я также пытался использовать операторы IF и несколько разных операторов UNION, но я не могу заставить его вернуть то, что я хочу.


person Jacob    schedule 19.11.2015    source источник


Ответы (2)


Возможно, вы захотите рассмотреть функцию COALESCE (выбирает первый ненулевой аргумент). Однако, если вы фильтруете пробелы вместо нулей, это может не сработать. В этом случае оператор CASE должен соответствовать вашим потребностям.

В вашем коде «конец» в вашем первом операторе case находится внутри min(), поэтому вы можете получить ошибку.

, (case when b.date = '27-JAN-13' then b.date else min(b.date) end) as Startdate

У меня возникли проблемы с пониманием того, что вы пытаетесь сделать, но на основе вашего описания я придумал приведенный ниже sql. Я не думаю, что вам нужно выполнять какую-либо фильтрацию в предложении where, так как вам нужен результат каждой отдельной строки. Вы просто хотите знать для каждой комбинации программы/файла, если самая ранняя дата после 27 января. Об этом позаботится оператор case в select.

«вернуть конкретную дату в качестве StartDate, но вернуть минимальную дату, если самая ранняя существующая дата больше, чем указанная дата начала»

select 
    a.program
    , a.match_file
    , case when min(b.date) > '27-JAN-13' then min(b.date) else '27-JAN-13' end as Startdate
from Schema1.program a, Schema1.detail b
where a.match_file = b.matchfile
group by a.program, a.match_file;
person pkm    schedule 19.11.2015
comment
Просто предложение, возможно, сначала ответьте или решите вопрос OP, а затем добавьте рекомендацию. Я был смущен, пытаясь увидеть, как объединение решает проблему. Тем не менее ваш ответ выглядит правильным. - person Juan Carlos Oropeza; 20.11.2015
comment
Спасибо за ответ пкм! Я попытался выполнить ваш запрос, но получил Ошибка ORA- 00932. Я попытался использовать to_date(), чтобы исправить это, но все равно получил ту же ошибку. - person Jacob; 20.11.2015
comment
О, подождите! Функция to_date действительно работала! Мне просто нужно было использовать узнаваемый формат даты. - person Jacob; 20.11.2015

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

select 
  a.program
  , a.match_file
  , (case when b.date = '27-JAN-13' then b.date else min(b.date) end) as Startdate
from Schema1.program a, Schema1.detail b
where a.match_file = b.matchfile
  and (case when b.date=' ' then min(b.date) else b.date end) = '27-JAN-13'
  group by a.program, a.match_file
;
person Lock    schedule 19.11.2015
comment
Спасибо за ответ! Я исправил синтаксис и запустил его снова, но теперь получаю ошибку ORA-00934: групповая функция здесь не разрешена. :( Любые предложения о том, как это исправить? - person Jacob; 20.11.2015
comment
Жаль, что я не видел эту часть. У вас не может быть агрегатной функции в предложении where. Уберите and (case when b.date=' ' then min(b.date) else b.date end) = '27-JAN-13' из своего запроса. - person Lock; 20.11.2015