Agregación · DISTINCT · varias columnas

COUNT(DISTINCT) con varias columnas en SQL

Cuenta combinaciones únicas de dos o más columnas sin confundir valores distintos con filas distintas.

Lectura: 8–10 minIntermediaEjemplo comprobado
Contenido de esta guía

Respuesta rápida

Si necesitas contar combinaciones únicas de varias columnas, el patrón más claro y portable es crear primero las filas distintas y contarlas después:

Patrón portable
SELECT COUNT(*) AS combinaciones_distintas
FROM (
  SELECT DISTINCT columna_a, columna_b
  FROM tabla
) AS combinaciones;

La subconsulta responde primero “¿qué combinaciones diferentes existen?”. El COUNT(*) exterior responde después “¿cuántas combinaciones son?”. Este orden evita depender de una sintaxis específica del motor y hace visible la unidad que estás contando.

No cuentas columnas: cuentas pares o tuplas

COUNT(DISTINCT ciudad) cuenta ciudades diferentes. Si añades otra columna, la pregunta cambia: ya no buscas ciudades únicas, sino combinaciones únicas como (Madrid, activo) y (Madrid, inactivo).

Modelo mental: trata las columnas elegidas como una clave compuesta temporal. Dos filas pertenecen a la misma combinación solo cuando coinciden en todas esas columnas.

Ejemplo comprobado: ciudad y estado del cliente

En la base educativa hay 12 clientes, 6 ciudades distintas y 7 combinaciones distintas de ciudad y activo. Madrid aparece con clientes activos e inactivos, por eso añade dos combinaciones aunque siga siendo una sola ciudad.

SQLite · ejecutado sobre la base educativa
SELECT COUNT(*) AS combinaciones_distintas
FROM (
  SELECT DISTINCT ciudad, activo
  FROM clientes
) AS combinaciones;
Resultado comprobado
combinaciones_distintas
7

Para ver qué está contando realmente la consulta, ejecuta solo la parte interior:

Ver las combinaciones antes de contarlas
SELECT DISTINCT ciudad, activo
FROM clientes
ORDER BY ciudad, activo;
Las 7 combinaciones distintas
ciudadactivo
A Coruña1
Bilbao1
Madrid0
Madrid1
Sevilla1
Valencia1
Zaragoza1

Sintaxis según el motor

El patrón con SELECT DISTINCT dentro de una subconsulta es una opción fácil de leer y funciona con PostgreSQL, MySQL, SQL Server y SQLite. Algunos motores ofrecen además una forma abreviada, pero no usan la misma sintaxis.

PostgreSQL

PostgreSQL permite construir un valor de fila y pasarlo como una sola expresión al agregado:

PostgreSQL
SELECT COUNT(DISTINCT (ciudad, activo))
FROM clientes;

MySQL

MySQL admite varias expresiones directamente dentro de COUNT(DISTINCT ...):

MySQL 8.4
SELECT COUNT(DISTINCT ciudad, activo)
FROM clientes;

SQL Server y SQLite

La sintaxis documentada de COUNT(DISTINCT expresión) recibe una sola expresión. Para contar combinaciones sin inventar una codificación propia, usa la subconsulta con SELECT DISTINCT y luego COUNT(*).

Qué cambia cuando hay NULL

Los atajos por motor no deben tratarse como intercambiables cuando alguna columna puede contener NULL. La documentación de MySQL indica que su forma con varias expresiones cuenta combinaciones que no contienen NULL. Si necesitas conservar combinaciones donde una de las columnas sea nula, el patrón con SELECT DISTINCT hace explícitas esas filas antes del recuento y resulta más fácil de verificar.

En este ejemplo ciudad y activo son columnas no nulas, así que las tres formas mostradas producen el mismo total de 7 en los motores donde su sintaxis correspondiente está disponible.

Errores frecuentes

Contar cada columna por separado

COUNT(DISTINCT ciudad) y COUNT(DISTINCT activo) responden dos preguntas independientes. Sumar o multiplicar esos resultados no te da necesariamente el número de combinaciones presentes.

Concatenar columnas sin un separador seguro

Patrón frágil
COUNT(DISTINCT columna_a || columna_b)

Valores diferentes pueden producir la misma cadena: ('ab','c') y ('a','bc') se convierten ambos en 'abc'. Además, el operador o función de concatenación varía entre motores.

Olvidar cuál es la unidad de análisis

Si la pregunta es “¿cuántas ciudades hay?”, usa una columna. Si es “¿cuántos estados de cliente existen por ciudad?”, necesitas la combinación. El SQL correcto depende primero de la pregunta.

Práctica guiada

Intermedia · agregaciónCuenta combinaciones de cliente y estado del pedido

Usa la tabla pedidos y devuelve cuántas combinaciones distintas de cliente_id y estado existen.

Resultado esperado: 14 combinaciones.

Criterio de éxito: la consulta debe contar combinaciones, no filas de pedido ni clientes por separado.

Pista 1

Empieza mostrando solo cliente_id y estado con SELECT DISTINCT.

Pista 2

Convierte ese resultado en una subconsulta con alias y aplica COUNT(*) por fuera.

Ver solución
Solución portable
SELECT COUNT(*) AS combinaciones
FROM (
  SELECT DISTINCT cliente_id, estado
  FROM pedidos
) AS combinaciones;

Primero se reduce la tabla a una fila por combinación de cliente y estado. Después se cuentan esas filas ya deduplicadas.

Qué debes recordar

  • COUNT(DISTINCT columna) cuenta valores distintos de una sola expresión.
  • Para varias columnas, piensa en combinaciones o tuplas, no en conteos independientes.
  • La subconsulta SELECT DISTINCT ... + COUNT(*) es un patrón claro y portable.
  • PostgreSQL y MySQL ofrecen atajos distintos; SQL Server y SQLite se expresan de forma más directa con la subconsulta.
  • Revisa el comportamiento de NULL antes de sustituir el patrón portable por un atajo del motor.

Conceptos relacionados

Fuentes técnicas consultadas