如何在特定条件后对特定列求和(Postgres)
Posted
技术标签:
【中文标题】如何在特定条件后对特定列求和(Postgres)【英文标题】:How to sum a specific column after a specific criteria (Postgres) 【发布时间】:2020-07-29 16:13:41 【问题描述】:我有这个代码
SELECT s.name AS School,
count(distinct u.id) filter (where ut.app_name = 'A' or ut.app_name = 'G') AS A,
count(distinct u.id) filter (where ut.app_name = 'B' or ut.app_name = 'J') AS B,
count(distinct u.id) filter (where ut.app_name = 'C') AS C,
count(distinct u.id) filter (where ut.app_name = 'D') AS D
FROM "public"."user_tokens" ut JOIN
"public"."users" u
ON ut.user_id = u.id JOIN
"public"."user_roles" ur
ON ut.user_id = ur.user_id JOIN
"public"."roles" r
ON ur.role_id = r.id JOIN
"public"."schools" s
ON ur.school_id = s.id
GROUP BY s.name
having count(distinct u.id) filter (where ut.app_name = 'A' or ut.app_name = 'G') > 0
and count(distinct u.id) filter (where ut.app_name = 'B' or ut.app_name = 'J') > 0
and count(distinct u.id) filter (where ut.app_name = 'C') > 0
上面代码的结果是
School A B C D
------------------------------------------
P 5 3 2 5
S 1 4 4 9
T 2 3 5 2
U 2 1 3 1
我想对 A 列求和,因此预期结果将是 10
。任何启示如何做到这一点?谢谢。
【问题讨论】:
请参阅postgresql.org/docs/current/queries-table-expressions.html 了解分组集。具体来说,rollup
就是你想要的。
其余列会怎样?
您想要单行作为结果还是现有结果加上新列?
我想要一个结果。刚刚尝试了像Select sum(A) FROM (....
这样的子查询,它起作用了
【参考方案1】:
您已经找到了解决方案,正如您在评论中所写,这只是为了展示如何使用别名而不是在 HAVING 中重复计算:
select sum(A)
from
(
SELECT s.name AS School,
count(distinct u.id) filter (where ut.app_name = 'A' or ut.app_name = 'G') AS A,
count(distinct u.id) filter (where ut.app_name = 'B' or ut.app_name = 'J') AS B,
count(distinct u.id) filter (where ut.app_name = 'C') AS C,
count(distinct u.id) filter (where ut.app_name = 'D') AS D -- can be removed, not used
FROM "public"."user_tokens" ut JOIN
"public"."users" u
ON ut.user_id = u.id JOIN
"public"."user_roles" ur
ON ut.user_id = ur.user_id JOIN
"public"."roles" r
ON ur.role_id = r.id JOIN
"public"."schools" s
ON ur.school_id = s.id
GROUP BY s.name
) as dt
where A> 0
and B > 0
and C > 0
【讨论】:
这个 where 子句是否只适用于子查询?如果它不是子查询,我可以使用它还是使用having子句? 别名只能在 ORDER BY 中使用(至少在标准 SQL 中),因为 Select 列表是在 之后 FROM/WHERE/GROUP BY/HAVING 计算的,因此您必须重复 HAVING 中的计数。但是在子查询(派生表)或公用表表达式/CTE 中分配的别名可以在外部 Select 中使用(有一组新的 WHERE/GROUP BY/HAVING),这很方便避免像巨大的 CASE 一样复制代码。以上是关于如何在特定条件后对特定列求和(Postgres)的主要内容,如果未能解决你的问题,请参考以下文章