DISTINCT elimina filas duplicadas
Por defecto, SELECT devuelve todas las filas que coinciden, incluidos los duplicados. Con DISTINCT le indicas a SQLite que agrupe las filas idénticas en las columnas que seleccionaste, de modo que cada combinación única aparezca una sola vez.
Cinco filas entran, tres salen. SQLite revisó la columna customer, descartó los repetidos y devolvió una fila por cada valor único. El orden no está garantizado: si te importa, agrega un ORDER BY.
DISTINCT se aplica a toda la lista del SELECT
Aquí es donde mucha gente se confunde. DISTINCT no elige una sola columna para eliminar duplicados, sino que deduplica filas completas tomando en cuenta todas las columnas que pongas en el SELECT.
Cada combinación única de (customer, country) aparece una sola vez. Si el mismo cliente apareciera con dos países distintos, verías ambas filas: para SQLite no son duplicados.
No existe una sintaxis tipo DISTINCT(customer) que ignore las demás columnas. Los paréntesis se ven tentadores, pero SELECT DISTINCT(customer), country se interpreta igual que SELECT DISTINCT customer, country: los paréntesis solo agrupan una expresión. Si lo que de verdad quieres es una fila por cliente con algún país concreto, eso ya es trabajo de GROUP BY junto con una función de agregación.
COUNT(DISTINCT col) en SQLite
Una necesidad muy habitual: ¿cuántos valores únicos hay en una columna? COUNT(*) cuenta filas, COUNT(col) cuenta valores no nulos, y COUNT(DISTINCT col) cuenta los valores únicos que no son NULL.
Cinco pedidos, tres clientes únicos y tres países únicos. COUNT(DISTINCT ...) es la forma agregada más útil de DISTINCT: la vas a usar siempre que necesites contar "cuántas cosas distintas aparecieron".
Ten en cuenta que SQLite solo permite una única columna dentro de COUNT(DISTINCT ...). Si quieres contar combinaciones únicas de varias columnas, envuélvelas en una subconsulta: SELECT COUNT(*) FROM (SELECT DISTINCT a, b FROM t).
Cómo trata DISTINCT los valores NULL
NULL tiene fama de raro en SQL porque NULL = NULL no se evalúa como TRUE, sino como NULL. Pero DISTINCT hace una excepción especial: a la hora de eliminar duplicados, todos los NULL se consideran iguales entre sí.
Vuelven tres filas: 'ada@example.com', 'dan@example.com' y un único NULL. Los tres correos NULL se fusionaron en uno solo. La misma regla se aplica a GROUP BY y a operaciones de conjuntos como UNION — viene bien recordarlo cuando estés investigando por qué "esa fila NULL aparece una vez en lugar de tres".
DISTINCT se ejecuta antes que ORDER BY y LIMIT
Las cláusulas de un SELECT siguen un orden lógico: FROM → WHERE → GROUP BY → HAVING → SELECT/DISTINCT → ORDER BY → LIMIT. Es decir, DISTINCT primero descarta los duplicados, luego ORDER BY ordena lo que queda y, por último, LIMIT recorta el resultado.
WHERE se queda con cuatro filas, DISTINCT colapsa los duplicados de Boris, ORDER BY los ordena alfabéticamente y LIMIT devuelve los dos primeros. Vale la pena repasar este flujo paso a paso: la confusión sobre el orden de los resultados casi siempre viene de olvidar en qué momento ocurre cada cosa.
DISTINCT vs GROUP BY en SQLite
Si lo único que buscas es eliminar duplicados, estas dos consultas devuelven exactamente las mismas filas:
Mismo resultado. La diferencia está en lo que puedes hacer después:
DISTINCTsirve para "dame filas únicas" y nada más.GROUP BYsirve para "agrupa filas y calcula algo por cada grupo" —COUNT(*),SUM(amount),MAX(created_at), etc.
Si te encuentras tirando de DISTINCT y luego te das cuenta de que también quieres un total por cliente, esa es la señal para pasarte a GROUP BY:
Una fila por cliente, con los agregados que querías. DISTINCT no podía hacer esto: no tiene forma de expresar "una fila por grupo más una suma."
Algunos detalles a tener en cuenta
- Rendimiento. Por lo general,
DISTINCTobliga a SQLite a ordenar o hashear las filas para detectar duplicados. En conjuntos de resultados grandes, conviene tener un índice sobre la columna (o columnas) que se deduplican. Y si hacesSELECT DISTINCTsobre todas las columnas de una tabla ancha, plantéate si de verdad necesitas todas esas columnas. DISTINCT *casi no se usa. Es válido —SELECT DISTINCT * FROM tdeduplica filas completas— pero si tu tabla tiene una clave primaria, cada fila ya es única, así que no aporta nada.- No lo confundas con
UNIQUE.UNIQUEes una restricción de tabla que impide que se inserten valores duplicados desde el principio.DISTINCT, en cambio, es un filtro en tiempo de consulta que oculta duplicados en el resultado. Herramientas distintas para tareas distintas.
A continuación: expresiones CASE
Cuando ya dominas cómo dar forma a las filas del resultado con SELECT, WHERE, ORDER BY y DISTINCT, el siguiente paso es la lógica condicional dentro de una consulta. Las expresiones CASE te permiten devolver valores distintos según ciertas condiciones: son el equivalente en SQL a una cadena de if/else, y las veremos en la siguiente página.
Preguntas frecuentes
¿Cómo funciona SELECT DISTINCT en SQLite?
SELECT DISTINCT elimina las filas duplicadas del resultado. SQLite compara todas las columnas que aparecen en el SELECT y deja una sola fila por cada combinación única. Se aplica después de WHERE y los JOIN, pero antes de ORDER BY y LIMIT.
¿Puedo usar DISTINCT sobre varias columnas en SQLite?
Sí, pero ten en cuenta que DISTINCT siempre actúa sobre toda la lista del SELECT, no sobre una columna suelta. Por ejemplo, SELECT DISTINCT city, country FROM users devuelve cada par único (city, country). No existe una sintaxis tipo DISTINCT(city) que ignore al resto de columnas; si necesitas eso, recurre a GROUP BY con una función de agregación.
¿Cómo trata DISTINCT los valores NULL en SQLite?
Para deduplicar, DISTINCT considera que un NULL es igual a otro NULL, así que varias filas con NULL se colapsan en una sola. Esto contrasta con el operador = dentro de un WHERE, donde NULL = NULL da resultado desconocido. Es una regla específica de DISTINCT, GROUP BY y UNION.
¿Qué diferencia hay entre DISTINCT y GROUP BY en SQLite?
Si solo quieres deduplicar, SELECT DISTINCT col y SELECT col FROM t GROUP BY col dan exactamente el mismo resultado. La diferencia está en la intención: usa DISTINCT cuando solo te interesan filas únicas, y GROUP BY cuando además vas a calcular agregaciones como COUNT(*) o SUM(amount) por grupo.