Получить значение 0 из числа без строк

У меня есть SELECT:

SELECT c FROM (
    SELECT "candidate_id" as id, count("candidate_id") as c
    FROM "Applicaions"
    GROUP BY "candidate_id"
) as s WHERE id= _SOME_ID_;

Но это возвращает только значение count > 0. Если count = 0 ничего не возвращает. Как я могу получить 0 для "Кандидата", у которого нет приложения?

Существует таблица "Кандидаты".
Мне нужно получить 0, если у кандидата нет приложений или не существует.

ИЗМЕНИТЬ

У меня есть:

SELECT COALESCE ((SELECT count("candidate_id") as c
FROM "Applicaions" WHERE "candidate_id"=_SOME_ID_
GROUP BY "candidate_id"), 0);

Он отлично работает. Но возможно ли это проще или это лучшее решение? Должен ли я создавать какие-либо индексы?

Ответы

Ответ 2

Вы не можете.

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

Как бы вы знали, что кандидат существует, если они не находятся в таблице Applications?

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

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

ИЗМЕНИТЬ

Теперь, когда у вас есть таблица Candidates, вы можете сделать это:

SELECT c.ID, (SELECT COUNT(a.*) FROM Applications a WHERE a.candidate_id = c.ID) 
FROM Candidate c
WHERE ....

Ответ 3

Может быть:

SELECT CASE c WHEN NULL THEN 0 ELSE c END
    FROM (
    SELECT "candidate_id" as id, count("candidate_id") as c
    FROM "Applicaions"
    GROUP BY "candidate_id"
) as s WHERE id= _SOME_ID_;

полагая, что "ничего" действительно NULL

Ответ 4

Вы не можете использовать это утверждение:

SELECT count("candidate_id") as c
FROM "Applicaions" WHERE "candidate_id"=_SOME_ID_
GROUP BY "candidate_id"

Он должен возвращать count(), и вам не нужен подзапрос.

ИЗМЕНИТЬ: Мэтью П.К. правильно, и Энди Патон лучше ответил;)

Ответ 5

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

SELECT c FROM (
 SELECT "Candidate"."candidate_id" as id, 
 count("Applications"."candidate_id") as c
 FROM "Candidate" LEFT JOIN "Applications" 
 ON "Applications"."candidate_id"="Candidate"."id"     
GROUP BY "Candidate"."candidate_id" ) as s WHERE id= _SOME_ID_;

Ответ 6

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

Этот ответ почти два года, но последние вопросы все еще ожидали.

Query

Можно ли написать это проще или это лучшее решение?

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

SELECT coalesce((SELECT count(candidate_id)
FROM   "Applications" WHERE candidate_id = _SOME_ID_), 0) AS c;
  • Условие WHERE ограничивается одним candidate_id и в списке SELECT имеется одна агрегатная функция. GROUP BY candidate_id был избыточным.

  • Псевдоним столбца был проглочен COALESCE(). Если вы хотите назвать полученный столбец, переместите псевдоним до конца.

  • Вам не нужны двойные кавычки для обычного строчного идентификатора.

Другая, более чистая (IMHO) форма должна была бы использовать LEFT JOIN:

SELECT count(a.candidate_id) AS c
FROM  (SELECT _SOME_ID_ AS candidate_id) x
LEFT   JOIN "Applicaions" a USING (candidate_id)

Это хорошо работает для нескольких идентификаторов:

WITH x(candidate_id) AS (
   VALUES
     (123::bigint)
    ,(345)
    ,(789)
   )
SELECT x.candidate_id, count(a.candidate_id) AS c
FROM   x
LEFT   JOIN "Applicaions" a USING (candidate_id)
GROUP  BY x.candidate_id;
  • LEFT JOIN обычно быстрее для длинного списка, чем несколько предложений WHERE или выражение IN.

Или, для всех строк в таблице "Кандидаты":

SELECT x.candidate_id, count(a.candidate_id) AS c
FROM   "Candidates" x
LEFT   JOIN "Applications" a USING (candidate_id)
GROUP  BY x.candidate_id;

Индексы

Нужно ли создавать какие-либо индексы?

Если производительность чтения важна, и таблица содержит больше, чем просто пару строк, вам определенно нужен индекс формы:

CREATE INDEX foo_idx ON "Applications" (candidate_id);

Так как это, по-видимому, является столбцом внешнего ключа, ссылающимся на "Candidates".candidate_id, вам, скорее всего, придется это начать.