计数不同结果为0时如何隐藏行? (Postgres)
How to hide rows when count distinct result is 0? (Postgres)
我有这个代码
SELECT "School"."name" AS "School",
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'A') AS "A",
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'B') AS "B",
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'C') AS "C",
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'D') AS "D"
FROM "public"."user_tokens"
LEFT JOIN "public"."users" "User" ON "public"."user_tokens"."user_id" = "User"."id"
LEFT JOIN "public"."user_roles" "User_2" ON "public"."user_tokens"."user_id" = "User_2"."user_id"
LEFT JOIN "public"."roles" "Role" ON "User_2"."role_id" = "Role"."id" LEFT JOIN "public"."schools" "School" ON "User_2"."school_id" = "School"."id"
GROUP BY "School"."name"
ORDER BY "B" desc
结果是这样的:
School A B C D
--------------------------------------------------
P 5 6 10 6
Q 1 0 0 0
R 2 7 0 6
S 0 8 9 0
是否可以隐藏包含值“0”的整行?这样的话,结果应该只有P校。
之后,如何计算不包含零值的“学校”?对于这种情况,结果应该是 1
谢谢。
GROUP BY "School"."name"
HAVING count... > 0
and count... > 0
ORDER BY "B" desc
您使用 having
子句并重复表达式
having count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'A') > 0 and
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'B') > 0 and
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'C') > 0 and
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'D')
尽管 Postgres 允许在 GROUP BY
中使用列别名,但它不允许在 HAVING
子句中使用列别名表达式(在我看来,这是扩展 SQL 标准的一种奇怪方式).
现在,您还可以简化和改进查询。首先,您需要匹配,所以只需使用 inner join
。其次,使用 table 别名。我也去掉了双引号——这是一个非常糟糕的主意:
SELECT s.name AS School,
count(distinct u.id) filter (where ut.app_name = 'A') AS A,
count(distinct u.id) filter (where ut.app_name = 'B') 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') > 0 and
count(distinct u.id) filter (where ut.app_name = 'B') > 0 and
count(distinct u.id) filter (where ut.app_name = 'C') > 0 and
count(distinct u.id) filter (where ut.app_name = 'D')
ORDER BY "B" desc
此外,您可以将查询作为 table 表达式 另一个SELECT
。在这个外部 SELECT
中,很容易通过添加过滤谓词过滤掉行:
WHERE "A" <> 0 and "B" <> 0 and "C" <> 0 and "D" <> 0
因此,您的查询可能如下所示:
SELECT
*,
count(*) over() as total_rows
from (
SELECT "School"."name" AS "School",
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'A') AS "A",
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'B') AS "B",
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'C') AS "C",
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'D') AS "D"
FROM "public"."user_tokens"
LEFT JOIN "public"."users" "User" ON "public"."user_tokens"."user_id" = "User"."id"
LEFT JOIN "public"."user_roles" "User_2" ON "public"."user_tokens"."user_id" = "User_2"."user_id"
LEFT JOIN "public"."roles" "Role" ON "User_2"."role_id" = "Role"."id" LEFT JOIN "public"."schools" "School" ON "User_2"."school_id" = "School"."id"
GROUP BY "School"."name"
) x
WHERE "A" <> 0 and "B" <> 0 and "C" <> 0 and "D" <> 0
ORDER BY "B" desc
如果您希望避免查询中的表达式冗余,这对于更复杂的表达式会派上用场。
我有这个代码
SELECT "School"."name" AS "School",
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'A') AS "A",
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'B') AS "B",
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'C') AS "C",
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'D') AS "D"
FROM "public"."user_tokens"
LEFT JOIN "public"."users" "User" ON "public"."user_tokens"."user_id" = "User"."id"
LEFT JOIN "public"."user_roles" "User_2" ON "public"."user_tokens"."user_id" = "User_2"."user_id"
LEFT JOIN "public"."roles" "Role" ON "User_2"."role_id" = "Role"."id" LEFT JOIN "public"."schools" "School" ON "User_2"."school_id" = "School"."id"
GROUP BY "School"."name"
ORDER BY "B" desc
结果是这样的:
School A B C D
--------------------------------------------------
P 5 6 10 6
Q 1 0 0 0
R 2 7 0 6
S 0 8 9 0
是否可以隐藏包含值“0”的整行?这样的话,结果应该只有P校。
之后,如何计算不包含零值的“学校”?对于这种情况,结果应该是 1
谢谢。
GROUP BY "School"."name"
HAVING count... > 0
and count... > 0
ORDER BY "B" desc
您使用 having
子句并重复表达式
having count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'A') > 0 and
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'B') > 0 and
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'C') > 0 and
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'D')
尽管 Postgres 允许在 GROUP BY
中使用列别名,但它不允许在 HAVING
子句中使用列别名表达式(在我看来,这是扩展 SQL 标准的一种奇怪方式).
现在,您还可以简化和改进查询。首先,您需要匹配,所以只需使用 inner join
。其次,使用 table 别名。我也去掉了双引号——这是一个非常糟糕的主意:
SELECT s.name AS School,
count(distinct u.id) filter (where ut.app_name = 'A') AS A,
count(distinct u.id) filter (where ut.app_name = 'B') 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') > 0 and
count(distinct u.id) filter (where ut.app_name = 'B') > 0 and
count(distinct u.id) filter (where ut.app_name = 'C') > 0 and
count(distinct u.id) filter (where ut.app_name = 'D')
ORDER BY "B" desc
此外,您可以将查询作为 table 表达式 另一个SELECT
。在这个外部 SELECT
中,很容易通过添加过滤谓词过滤掉行:
WHERE "A" <> 0 and "B" <> 0 and "C" <> 0 and "D" <> 0
因此,您的查询可能如下所示:
SELECT
*,
count(*) over() as total_rows
from (
SELECT "School"."name" AS "School",
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'A') AS "A",
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'B') AS "B",
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'C') AS "C",
count(distinct "User"."id") filter (where "public"."user_tokens"."app_name" = 'D') AS "D"
FROM "public"."user_tokens"
LEFT JOIN "public"."users" "User" ON "public"."user_tokens"."user_id" = "User"."id"
LEFT JOIN "public"."user_roles" "User_2" ON "public"."user_tokens"."user_id" = "User_2"."user_id"
LEFT JOIN "public"."roles" "Role" ON "User_2"."role_id" = "Role"."id" LEFT JOIN "public"."schools" "School" ON "User_2"."school_id" = "School"."id"
GROUP BY "School"."name"
) x
WHERE "A" <> 0 and "B" <> 0 and "C" <> 0 and "D" <> 0
ORDER BY "B" desc
如果您希望避免查询中的表达式冗余,这对于更复杂的表达式会派上用场。