![](/img/trans.png)
[英]Return multiple COUNT fields for distinct values per a unique ID based on two criteria conditions
[英]How To Count Distinct Values Based on Two Different Criteria?
我想從一列中區分,但有兩個不同的標准。
我想在 count_1 上過濾所有 email 不包含 yopmail 並在count_1
上過濾所有 email 不包含count_2
。
我試過這個 SQL 但我不知道如何過濾count_2
。 我的代碼同時過濾了count_1
和count_2
。
SELECT "School"."name" AS "School", count(distinct "public"."users"."id") AS "count_1", count(distinct "public"."users"."id") AS "count_2"
FROM "public"."users"
LEFT JOIN "public"."user_roles" "User Roles" ON "public"."users"."id" = "User Roles"."user_id"
LEFT JOIN "public"."roles" "Role" ON "User Roles"."role_id" = "Role"."id"
LEFT JOIN "public"."schools" "School" ON "User Roles"."school_id" = "School"."id"
WHERE ("Role"."name" = 'Student'
AND "public"."users"."deleted_at" IS NULL
AND "public"."users"."activated_at" IS NOT NULL
AND NOT (lower("public"."users"."email") like '%yopmail%'))
GROUP BY "School"."name"
ORDER BY "School"."name" ASC
結果是這樣的:它同時過濾了count
但我想從count_1
和count_2
中獲得不同的值。
School | Count_1 | Count_2 |
+------------+-----------+-----------+
| A | 11 | 11 |
| B | 20 | 20 |
| C | 34 | 34 |
+------------+-----------+-----------+
您可以通過過濾聚合來實現:
SELECT "School"."name" AS "School",
count(distinct "public"."users"."id") AS "count_1",
-- the following only counts users where the email column does not contain the value gmail
count(distinct users.id) filter (where email not like '%gmail%') AS "count_2"
FROM "public"."users"
LEFT JOIN "public"."user_roles" "User Roles" ON "public"."users"."id" = "User Roles"."user_id"
LEFT JOIN "public"."roles" "Role" ON "User Roles"."role_id" = "Role"."id"
LEFT JOIN "public"."schools" "School" ON "User Roles"."school_id" = "School"."id"
WHERE ("Role"."name" = 'Student'
AND "public"."users"."deleted_at" IS NULL
AND "public"."users"."activated_at" IS NOT NULL
AND NOT (lower("public"."users"."email") like '%yopmail%'))
GROUP BY "School"."name"
ORDER BY "School"."name" ASC
經典的方法是使用 CASE 表達式。
SELECT "School"."name" AS "School",
count(distinct CASE WHEN NOT (lower("public"."users"."email") like '%yopmail%') THEN "public"."users"."id" else NULL END) AS "count_1",
count(distinct CASE WHEN NOT (lower("public"."users"."email") like '%gmail%') THEN "public"."users"."id" else NULL END) AS "count_2"
FROM "public"."users"
LEFT JOIN "public"."user_roles" "User Roles" ON "public"."users"."id" = "User Roles"."user_id"
LEFT JOIN "public"."roles" "Role" ON "User Roles"."role_id" = "Role"."id"
LEFT JOIN "public"."schools" "School" ON "User Roles"."school_id" = "School"."id"
WHERE ("Role"."name" = 'Student'
AND "public"."users"."deleted_at" IS NULL
AND "public"."users"."activated_at" IS NOT NULL)
GROUP BY "School"."name"
ORDER BY "School"."name" ASC
如果您使用過濾子句,請將其應用於 count_1 和 count_2,並從 WHERE 子句中刪除 email 條件。
SELECT "School"."name" AS "School",
count(distinct "public"."users"."id") filter (where NOT (lower("public"."users"."email") like '%yopmail%')) AS "count_1",
count(distinct "public"."users"."id") filter (where NOT (lower("public"."users"."email") like '%gmail%')) AS "count_2"
FROM "public"."users"
LEFT JOIN "public"."user_roles" "User Roles" ON "public"."users"."id" = "User Roles"."user_id"
LEFT JOIN "public"."roles" "Role" ON "User Roles"."role_id" = "Role"."id"
LEFT JOIN "public"."schools" "School" ON "User Roles"."school_id" = "School"."id"
WHERE ("Role"."name" = 'Student'
AND "public"."users"."deleted_at" IS NULL
AND "public"."users"."activated_at" IS NOT NULL)
GROUP BY "School"."name"
ORDER BY "School"."name" ASC
見下文: SQL 小提琴
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.