Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

190
Vistas
How To Count Distinct Values Based on Two Different Criteria?

I want to count distinct from one column but with 2 different criteria.

I want filter all email does not contain yopmail on count_1 and filter all email does not contain gmail on count_2.

I've tried this SQL but I have no idea how to filter for count_2. My code is filtering both count_1 and 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

The result is like this: It's filtering both count but I want to have different values from count_1 and count_2.

 School      | Count_1   | Count_2   |
+------------+-----------+-----------+
| A          | 11        | 11        | 
| B          | 20        | 20        |
| C          | 34        | 34        |
+------------+-----------+-----------+
over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

You can achieve that with a filtered aggregation:

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
over 4 years ago · Santiago Trujillo Denunciar

0

The classic method is to use the CASE expression.

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

If you use filter clause, apply it to count_1 and count_2, and delete the email condition from the WHERE clause.

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

See below: SQL Fiddle

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda