Вопрос: Получить значение 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);

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


15


источник


Ответы:


Вам необходимо использовать функцию COALESCE в PostgreSQL http://developer.postgresql.org/pgdocs/postgres/functions-conditional.html

По сути вам нужно сказать SQL, как обращаться NULLs. т. е. когда NULL вернуть 0,


13



Вы не можете.

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

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

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

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

РЕДАКТИРОВАТЬ

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

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

5



Может быть:

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


2



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

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

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

EDIT: Мэтью PK является правильным, и Энди Патон лучше ответить;)


1



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

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_;

1



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

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

запрос

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

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

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, вы должны, скорее всего, иметь это для начала.


1