2013-05-22 3 views
2

Я пытаюсь выполнить следующий запрос:Выберите заявление в NVL

select a.*, 
    case when NVL (SELECT max(b.field1) 
     FROM b 
     where b.field2 = a.tbl_a_PK , 'TRUE') = 'TRUE' 
      then 'has no data in b' 
      else 'has data in b' end as b_status 
from a 

Я проверил и выберите внутри NVL возвращает только 1 значение (так что не должно быть проблемой там). Однако я получаю «ORA-00936: недостающее выражение»

+0

Как раз сейчас я понял, что могу так же легко сделать это: выберите a. *, Case when (SELECT max (b.field1) FROM b, где b.field2 = a.tbl_a_PK) является нулевым, тогда 'не имеет данных в b' else 'имеет данные в b' end как b_status из a. но мне все еще интересно, в чем проблема с nvl. –

+0

Вам нужны скобки, которые заключают в себе функцию select. Лучше всего использовать Coalesce() вместо Nvl() –

ответ

1

Если вы ищете для записей в которых есть/нет связанных записей в б

select a.*, 
     case when b.field2 is null then 'has no data in b' 
            else 'has data in b' 
     as b_status 
from a left outer join b 
on a.tbl_a_PK = b.field2; 

Если сделать это

1

функция NVL (string1, replace_with) требует 2 параметра, см документации здесь: http://www.techonthenet.com/oracle/functions/nvl.php
Ora 10г документы http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions105.htm
Поскольку вы знаете проблему, этот запрос может это исправить:

select a.*, 
     case 
     when (SELECT NVL(b.field2, 0) FROM b where b.field2 = a.tbl_a_PK and rownum = 1) > 0 then 
      'has data in b' 
     else 
      'has no data in b' 
     end b_status 
    from a 

и работает быстрее.
Вам не нужно max(), чтобы проверить, существует ли значение в другой таблице, просто проверьте, не является ли первичный ключ непустым.

1

NVL() требует 2 параметра: выражение для проверки и значение по умолчанию, например. nvl(some_field, 111). Вам просто нужно выделить параметр запроса в фигурные скобки и обеспечивают второй параметр, как в этом заявлении:

select nvl((select 1 from dual), 34) from dual 

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

именно ваше заявление должно выглядеть следующим образом:

select 
    a.*, 
    case when NVL(
       (SELECT max(b.field1) 
       FROM b 
       where b.field2 = a.tbl_a_PK 
      ), 
       'TRUE' 
      ) = 'TRUE' 
     then 'has no data in b' 
     else 'has data in b' end     as b_status 
from a 

Надеется, что это помогает ...

Update С точкой зрения производительности лучше использовать exists, а затем max:

select 
    a.*, 
    case when exists 
       (SELECT null 
       FROM b 
       where b.field2 = a.tbl_a_PK 
         and 
         b.field2 is not null 
         and 
         rownum = 1 
      ), 
     then 'has data in b' 
     else 'has no data in b' end     as b_status 
from a