从没有行的计数中获取0值

Mik*_*onn 20 sql postgresql select count

我有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_;
Run Code Online (Sandbox Code Playgroud)

但是这只会返回一个值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);
Run Code Online (Sandbox Code Playgroud)

它完美地运作.但是有可能把它写得更简单或者这是最好的解决方案吗?我应该创建任何索引吗?

dia*_*man 16

你需要在PostgreSQL中使用COALESCE函数http://developer.postgresql.org/pgdocs/postgres/functions-conditional.html

基本上你需要告诉SQL如何NULLNULL返回时处理sie 0.


Mat*_*hew 5

你不能.

如果您的候选人没有申请,那么您无法阅读其candidate_id价值

如果候选人没有他们在Applications桌子上,你怎么知道?

在您的示例代码中,没有候选人,因此您不可能说特定候选人没有应用程序.通过该逻辑,存在无限数量的候选者具有零应用.

您需要一份候选人表格才能获得这些信息...除非您的意图是假设候选人存在,因为您是通过身份证件提出的?

编辑

既然你有一张Candidates桌子就可以做到这一点:

SELECT c.ID, (SELECT COUNT(a.*) FROM Applications a WHERE a.candidate_id = c.ID) 
FROM Candidate c
WHERE ....
Run Code Online (Sandbox Code Playgroud)


Erw*_*ter 5

这篇相关文章的作者让我意识到这个问题,他在读完这里后相信他的问题无法解决。嗯,可以。

这个答案已经快两年了,但最终的问题仍然悬而未决。

询问

是否可以写得更简单或者这是最好的解决方案?

要测试单个 ID,您找到的查询很好。您可以简化:

SELECT coalesce((SELECT count(candidate_id)
FROM   "Applications" WHERE candidate_id = _SOME_ID_), 0) AS c;
Run Code Online (Sandbox Code Playgroud)
  • 条件WHERE限制为单个candidate_id,并且列表中只有一个聚合函数SELECTGROUP BY candidate_id是多余的。

  • 列别名被 吞没了COALESCE()。如果要命名结果列,请将别名移至末尾。

  • 常规小写标识符不需要双引号。

另一种更干净的(恕我直言)形式是使用LEFT JOIN

SELECT count(a.candidate_id) AS c
FROM  (SELECT _SOME_ID_ AS candidate_id) x
LEFT   JOIN "Applicaions" a USING (candidate_id)
Run Code Online (Sandbox Code Playgroud)

这对于多个 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;
Run Code Online (Sandbox Code Playgroud)
  • 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;
Run Code Online (Sandbox Code Playgroud)

索引

我应该创建任何索引吗?

如果读取性能很重要并且表不仅仅包含几行,那么您肯定需要以下形式的索引:

CREATE INDEX foo_idx ON "Applications" (candidate_id);
Run Code Online (Sandbox Code Playgroud)

由于这似乎是引用的外键列"Candidates".candidate_id,因此您很可能应该从它开始。