🧚 ¡Oye! Beekeeper Studio es una GUI de bases de datos rápida, moderna y de código abierto Descarga
21 de julio de 2025 Por Matthew Rathbone

COUNT(DISTINCT column) cuenta cuántos valores distintos tiene una columna: un valor que aparece diez veces cuenta una sola vez, y los NULL no cuentan para nada. Los ejemplos funcionan en PostgreSQL, MySQL, SQLite y SQL Server.

Cómo usar COUNT DISTINCT

Pon DISTINCT dentro de COUNT(), antes de la columna o expresión que quieres contar:

COUNT(DISTINCT expression)

Se entiende mejor junto a las otras dos formas de COUNT. COUNT(*) cuenta filas, COUNT(column) cuenta las filas donde la columna no es NULL, y COUNT(DISTINCT column) cuenta los distintos valores que no son NULL:

-- Input: orders
-- order_id | customer_id
-- ---------+------------
-- 1        | 1042
-- 2        | 1077
-- 3        | 1042
-- 4        | NULL

SELECT COUNT(*) AS all_rows,
       COUNT(customer_id) AS with_customer,
       COUNT(DISTINCT customer_id) AS customers
FROM orders;

-- Output:
-- all_rows | with_customer | customers
-- ---------+---------------+----------
-- 4        | 3             | 2

Cuatro pedidos vinieron de dos clientes: 1042 pidió dos veces, y el pedido 4 no tiene cliente.

Reglas que debes conocer

  • Los NULL no se cuentan. Si un valor faltante debe contar como uno más, súmalo tú:
-- Input: the orders table above

SELECT COUNT(DISTINCT customer_id)
       + MAX(CASE WHEN customer_id IS NULL THEN 1 ELSE 0 END) AS customers_and_guests
FROM orders;
-- Output: 3
  • MySQL y SQL Server ignoran mayúsculas y minúsculas por defecto, así que cuentan 'SQL' y 'sql' como un solo valor. Cuenta LOWER(tag) cuando no deban importar las mayúsculas:
-- Input: tags
-- post_id | tag
-- --------+---------
-- 1       | SQL
-- 2       | sql
-- 3       | Postgres

SELECT COUNT(DISTINCT tag) FROM tags;
-- Output: 3 (2 in MySQL and SQL Server)

SELECT COUNT(DISTINCT LOWER(tag)) FROM tags;
-- Output: 2
  • DISTINCT también funciona dentro de SUM y AVG, pero descarta valores repetidos, no filas repetidas. Dos productos distintos con el mismo precio se suman solo una vez:
-- Input: order_lines
-- product  | price
-- ---------+------
-- Pen      | 2.00
-- Pencil   | 2.00
-- Notebook | 5.00

SELECT SUM(price) AS total, SUM(DISTINCT price) AS distinct_total FROM order_lines;

-- Output:
-- total | distinct_total
-- ------+---------------
-- 9.00  | 7.00

Sintaxis alternativa

COUNT(DISTINCT ...) acepta una sola columna. Para contar las distintas combinaciones de varias columnas, cuenta las filas de una subconsulta con DISTINCT. PostgreSQL y MySQL también tienen atajos:

-- Input: orders
-- order_id | customer_id | product_id
-- ---------+-------------+-----------
-- 1        | 1           | 23
-- 2        | 12          | 3
-- 3        | 1           | 23
-- 4        | 12          | 5

SELECT COUNT(*) FROM (SELECT DISTINCT customer_id, product_id FROM orders) AS pairs;
-- Output: 3

-- PostgreSQL
SELECT COUNT(DISTINCT (customer_id, product_id)) FROM orders;
-- Output: 3

-- MySQL
SELECT COUNT(DISTINCT customer_id, product_id) FROM orders;
-- Output: 3

También vas a ver las columnas unidas en una sola cadena con CONCAT(). Necesita un separador: sin él, el cliente 1 con el producto 23 y el cliente 12 con el producto 3 se convierten ambos en '123':

-- Input: the orders table above

SELECT COUNT(DISTINCT CONCAT(customer_id, product_id)) FROM orders;
-- Output: 2

SELECT COUNT(DISTINCT CONCAT(customer_id, '_', product_id)) FROM orders;
-- Output: 3

Un conteo exacto de distintos tiene que ordenar o aplicar hash a cada valor, lo cual se vuelve lento en tablas muy grandes. SQL Server tiene APPROX_COUNT_DISTINCT(), que es más rápido y se mantiene dentro del 2% del conteo exacto el 97% de las veces:

-- SQL Server
-- Input: the orders table above

SELECT APPROX_COUNT_DISTINCT(customer_id) AS customers FROM orders;
-- Output: 2

¿Cuándo deberías usar COUNT DISTINCT?

Usa COUNT DISTINCT cuando la pregunta es “¿cuántos … distintos?” y no “¿cuántas filas?”. La mayoría de esas preguntas caen en uno de estos cuatro casos.

Contar visitantes, clientes o productos únicos

Un registro de visitas, pedidos o ventas guarda al mismo visitante, cliente o producto una y otra vez. COUNT DISTINCT sobre su ID convierte esas filas en un conteo de cabezas.

Contar valores únicos en cada grupo

Agrega GROUP BY y obtienes un conteo de distintos por grupo: estudiantes distintos por curso, productos distintos por vendedor, clientes distintos por mes.

Contar combinaciones únicas de columnas

A veces dos filas solo son “iguales” cuando coinciden dos columnas: el mismo usuario con el mismo tipo de problema, o la misma ruta entre dos aeropuertos. Cuenta las combinaciones con alguna de las formas de varias columnas de “Sintaxis alternativa”.

Contar valores únicos que cumplen una condición

Pon una expresión CASE dentro de COUNT(DISTINCT ...) para contar solo algunas filas. El CASE devuelve NULL para las filas que no quieres, y los NULL no se cuentan, así que una sola consulta puede devolver varios conteos filtrados lado a lado.

Ejemplos reales de COUNT DISTINCT

Usuarios activos mensuales

Cuenta los usuarios que hicieron algo en septiembre, sin importar cuántas veces regresaron:

-- Input: events
-- event_id | user_id | event_date
-- ---------+---------+-----------
-- 1        | 301     | 2026-08-30
-- 2        | 302     | 2026-09-02
-- 3        | 302     | 2026-09-15
-- 4        | 305     | 2026-09-21
-- 5        | 302     | 2026-10-01

SELECT COUNT(DISTINCT user_id) AS active_users
FROM events
WHERE event_date >= '2026-09-01' AND event_date < '2026-10-01';
-- Output: 2

Productos vendidos por cada vendedor

COUNT(*) da el número de ventas de cada vendedor, y COUNT(DISTINCT product) cuántos productos distintos abarcaron esas ventas:

-- Input: sales
-- vendor     | product  | color
-- -----------+----------+------
-- Acme       | Mug      | Red
-- Acme       | Mug      | Blue
-- Acme       | Mug      | Red
-- Acme       | Tote Bag | Red
-- Brightside | Notebook | Black

SELECT vendor, COUNT(*) AS sales, COUNT(DISTINCT product) AS products
FROM sales
GROUP BY vendor;

-- Output:
-- vendor     | sales | products
-- -----------+-------+---------
-- Acme       | 4     | 2
-- Brightside | 1     | 1

Rutas que vuela una aerolínea

Una ruta es un origen y un destino juntos. Dos vuelos de LHR a JFK son una sola ruta, pero de JFK a LHR es otra:

-- Input: flights
-- flight_no | origin | destination
-- ----------+--------+------------
-- 101       | LHR    | JFK
-- 105       | LHR    | JFK
-- 102       | JFK    | LHR
-- 301       | LHR    | LAX

SELECT COUNT(*) AS routes
FROM (SELECT DISTINCT origin, destination FROM flights) AS r;
-- Output: 3

Clientes según el precio de lo que compraron

Cuenta los clientes que compraron los productos 100 a 200 y luego sepáralos según el precio de sus pedidos. El cliente 7 hizo dos pedidos baratos pero cuenta una vez, y el producto del cliente 15 está fuera del rango:

-- Input: orders
-- order_id | customer_id | product_id | price
-- ---------+-------------+------------+-------
-- 1        | 7           | 105        | 25.00
-- 2        | 7           | 142        | 40.00
-- 3        | 9           | 150        | 120.00
-- 4        | 12          | 188        | 310.00
-- 5        | 15          | 260        | 30.00

SELECT
  COUNT(DISTINCT customer_id) AS customers,
  COUNT(DISTINCT CASE WHEN price BETWEEN 1 AND 50 THEN customer_id END) AS low_spenders,
  COUNT(DISTINCT CASE WHEN price BETWEEN 51 AND 150 THEN customer_id END) AS mid_spenders,
  COUNT(DISTINCT CASE WHEN price > 150 THEN customer_id END) AS high_spenders
FROM orders
WHERE product_id BETWEEN 100 AND 200;

-- Output:
-- customers | low_spenders | mid_spenders | high_spenders
-- ----------+--------------+--------------+--------------
-- 3         | 1            | 1            | 1

Un cliente con pedidos en dos rangos de precio se cuenta en ambos.

Más lecturas sobre COUNT DISTINCT

En este blog:

Documentación oficial:

Beekeeper Studio es un cliente de bases de datos gratuito y de código abierto

La mejor herramienta de consultas y edición de SQL que he usado. Tiene todo lo que necesito para administrar mi base de datos. - ⭐⭐⭐⭐⭐ Mit

Beekeeper Studio es rápido, intuitivo y fácil de usar. Es compatible con muchísimas bases de datos y funciona de maravilla en Windows, Mac y Linux.

La versión de Beekeeper para Linux tiene el 100% de las funciones, sin recortes ni concesiones.

Lo que dicen los usuarios de Beekeeper Studio

★★★★★
"Beekeeper Studio reemplazó por completo mi antiguo flujo de trabajo con SQL. Es rápido, intuitivo y hace que trabajar con bases de datos vuelva a ser agradable."
— Alex K., desarrollador de bases de datos
★★★★★
"He probado muchas GUI de bases de datos, pero Beekeeper logra el equilibrio perfecto entre funciones y simplicidad. Simplemente funciona."
— Sarah M., ingeniera full stack

¿Listo para mejorar tu flujo de trabajo con SQL?

download Descarga gratis