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如何NULL在NULL返回时处理sie 0.
你不能.
如果您的候选人没有申请,那么您无法阅读其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)
这篇相关文章的作者让我意识到这个问题,他在读完这里后相信他的问题无法解决。嗯,可以。
这个答案已经快两年了,但最终的问题仍然悬而未决。
是否可以写得更简单或者这是最好的解决方案?
要测试单个 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,并且列表中只有一个聚合函数SELECT。GROUP 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,因此您很可能应该从它开始。