sql — вернуть строку постоянных значений, если строки не существует

Я хочу иметь возможность возвращать строку none, none, 0, если из запроса не возвращается строка. У меня есть этот SQL:

select first, last, count(address)
from employee
where last in ('james', 'smith', 'hankers')
group by first, last
union all 
select 'none', 'none', 0
from dual
where not exists (select * from employee where last in ('james', 'smith', 'hankers'));

Из базы данных существует запись для james и smith, но нет записи для hankers.

Но этот запрос возвращается только тогда, когда запись существует. Не возвращает none, none, 0.

Что я здесь делаю неправильно?

РЕДАКТИРОВАТЬ: В этом примере я передаю 3 жестко закодированных значения как last, но я хотел бы знать обходной путь, если бы мы передавали значения в качестве параметра списка, например (:last), через getJdbcTemplate.


person qollers    schedule 12.11.2016    source источник
comment
вы можете использовать rowcount, как здесь: stackoverflow.com/questions/2884996/   -  person aguetat    schedule 12.11.2016
comment
Какую БД вы использовали?   -  person vipin    schedule 12.11.2016
comment
Окей, я поддерживаю aguetat, но его пример в msSql, а вот в oracle можно выбрать count для проверки.   -  person vipin    schedule 12.11.2016


Ответы (2)


NOT EXISTS применяется с учетом всех перечисленных значений. Таким образом, если существует какое-либо одно значение, то NOT EXISTS не выполняется.

В качестве обходного пути вы можете использовать встроенную таблицу с указанными значениями и присоединить к ней исходную таблицу:

select coalesce(t2.first, 'none'), 
       coalesce(t2.last, 'none'), 
       count(t2.address)
from (
   select 'james' as last
   union all
   select 'smith'
   union all
   select 'hankers') t1
left join employee t2 ON t1.last = t2.last
group by coalesce(t2.first, 'none'), 
         coalesce(t2.last, 'none')

Если совпадения нет, как в случае с last='hankers', то count(t2.address) оценивается как 0 и, таким образом, возвращается 'none', 'none', 0.

person Giorgos Betsos    schedule 12.11.2016
comment
Я понимаю. Спасибо. Тем не менее, я должен был уточнить в исходном сообщении, но какой был бы обходной путь, если бы мы не знали точный размер параметров last? В примере я передаю жестко закодированные 3 значения как last, но в моем реальном SQL я не знаю значений и передаю параметр списка, подобный этому in (:last); - person qollers; 12.11.2016
comment
@qollers Другим обходным путем может быть заполнение временной таблицы всеми значениями. Информация о фамилиях должна храниться в какой-то реляционной структуре, если вы хотите ее получить. - person Giorgos Betsos; 12.11.2016

Пусть это поможет тебе,

_count NUMBER(10);

select count(*) into _count
from employee
where last in ('james', 'smith', 'hankers');

if(_count > 0)
then
   select first, last, count(address) c
   from employee
   where last in ('james', 'smith', 'hankers')
   group by first, last
else
   select 'none' first, 'none' last, 0 c   from dual
end if
person vipin    schedule 12.11.2016
comment
_count NUMBER(10); здесь мы объявляем числовую переменную? Извините, я новичок в SQL - person qollers; 12.11.2016
comment
Если вы используете хранимую процедуру для выполнения операций с БД, вы можете объявить переменные. - person vipin; 13.11.2016