Las tablas de TiendaVerde no tienen filas duplicadas: cada una tiene su clave primaria id, así que no hay dos iguales. Y sin embargo, en cuanto proyectas solo una parte de las columnas, empiezan a aparecer repeticiones por todas partes. Preguntar "¿en qué países tengo clientes?" sobre una tabla de quince filas devuelve quince respuestas cuando solo hay tres países distintos. En esta lección aprenderás por qué ocurre, cómo lo resuelve DISTINCT, por qué actúa sobre la combinación completa de columnas del SELECT (el malentendido más habitual del módulo), dónde encaja en el orden lógico de ejecución, y cuándo la aparición de DISTINCT en una consulta es en realidad la señal de que la consulta está mal planteada.

Contenido

  1. Por qué aparecen filas repetidas
  2. DISTINCT sobre una columna
  3. DISTINCT sobre varias columnas: el malentendido clásico
  4. Dónde encaja DISTINCT en el orden lógico
  5. DISTINCT combinado con WHERE y con ORDER BY
  6. COUNT(DISTINCT columna): un anticipo del módulo 4
  7. DISTINCT ON: la extensión de PostgreSQL
  8. El coste de DISTINCT y cuándo delata un error
  9. Errores Comunes y Consejos
  10. Ejercicios
  11. Conclusión

  1. Por qué aparecen filas repetidas

Empecemos por el problema:

SELECT pais
FROM clientes;
pais
España
España
España
España
España
España
Portugal
Portugal
Francia
Francia
España
España
España
España
España

15 filas. Una por cliente, porque SELECT devuelve una fila de resultado por cada fila de origen. La proyección ha eliminado las columnas que hacían única a cada fila (id, email, nombre...), y lo que queda se repite.

Es importante entender que esto no es un fallo de los datos. En el modelo relacional puro una relación es un conjunto y no admite duplicados, pero SQL no trabaja con conjuntos sino con multiconjuntos (bags): permite repeticiones y solo las elimina si se lo pides explícitamente. Fue una decisión pragmática de los diseñadores del lenguaje: eliminar duplicados cuesta tiempo, y en la mayoría de las consultas no hace falta.

Lo mismo con las ciudades:

SELECT ciudad
FROM clientes;

Devuelve 15 filas con Valencia cuatro veces y Barcelona dos.

  1. DISTINCT sobre una columna

La palabra clave DISTINCT se escribe inmediatamente después de SELECT y elimina las filas repetidas del resultado:

SELECT DISTINCT pais
FROM clientes;
pais
España
Portugal
Francia

3 filas. Ahora sí has respondido a la pregunta "¿en qué países tengo clientes?".

SELECT DISTINCT ciudad
FROM clientes;
ciudad
Valencia
Castellón
Madrid
Barcelona
Lisboa
Oporto
Lyon
París
Alicante
Sevilla
Zaragoza

11 filas de las 15: Valencia aparecía 4 veces y Barcelona 2.

Otro caso útil: saber qué métodos de pago se usan realmente. La restricción CHECK de la tabla admite cuatro, pero ¿se usan todos?

SELECT DISTINCT metodo_pago
FROM pedidos;
metodo_pago
tarjeta
transferencia
paypal
contrareembolso

Los cuatro. Y los estados:

SELECT DISTINCT estado
FROM pedidos;
estado
entregado
enviado
pagado
pendiente
cancelado

Los cinco valores del dominio están representados.

Muy importante: DISTINCT no ordena. Los resultados de arriba salen en un orden que PostgreSQL elige según cómo haya eliminado los duplicados (normalmente con una tabla hash, cuyo orden es impredecible). Podrías ver Francia, España, Portugal perfectamente. Si quieres un orden concreto, ORDER BY (sección 5).

Dos detalles de sintaxis:

  1. DISTINCT afecta a toda la lista de columnas, no a la que tiene al lado. SELECT DISTINCT pais, ciudad no es "el pais distinto y la ciudad": es la sección 3.
  2. DISTINCT(pais) funciona, pero es engañoso: esos paréntesis son los de una expresión, no los de una función. SELECT DISTINCT (pais), ciudad sigue aplicando DISTINCT a las dos columnas. No escribas DISTINCT con paréntesis; induce a error a quien lo lea.

Y un apunte sobre nulos: para DISTINCT, todos los NULL cuentan como un mismo valor y se colapsan en una sola fila. Es una excepción deliberada a la regla de que NULL no es igual a NULL, y la verás en el ejercicio 3.

  1. DISTINCT sobre varias columnas: el malentendido clásico

Esta es la parte que hay que interiorizar bien:

SELECT DISTINCT pais, ciudad
FROM clientes;
pais ciudad
España Valencia
España Castellón
España Madrid
España Barcelona
España Alicante
España Sevilla
España Zaragoza
Portugal Lisboa
Portugal Oporto
Francia Lyon
Francia París

11 filas, y España aparece siete veces. ¿No habíamos dicho que DISTINCT elimina duplicados?

Los ha eliminado. Lo que ocurre es que DISTINCT compara la fila completa, no columna por columna. (España, Valencia) y (España, Madrid) son dos filas distintas, aunque compartan el primer valor. Solo se elimina una fila si todos sus valores coinciden con los de otra: (España, Valencia) aparecía cuatro veces en la tabla y ha quedado una.

Lo que mucha gente cree que hace Lo que hace de verdad
"Un valor distinto de pais, y para cada uno la ciudad" Cada combinación distinta de (pais, ciudad)
Debería devolver 3 filas Devuelve 11

Piénsalo así: DISTINCT mira la fila del resultado como si fuera una tupla y se pregunta "¿he visto ya exactamente esta tupla?".

Otro ejemplo, esta vez sobre el catálogo: ¿qué combinaciones de categoría y proveedor existen?

SELECT DISTINCT categoria_id, proveedor_id
FROM productos;

Con ORDER BY para poder leerlo (lo justificamos en la sección 5):

SELECT DISTINCT categoria_id, proveedor_id
FROM productos
ORDER BY categoria_id, proveedor_id;
categoria_id proveedor_id
1 1
1 2
2 3
2 4
3 3
3 5
4 1
4 2
4 3
5 4
5 5
6 5

12 combinaciones a partir de 20 productos. Se lee mucha información de negocio en esa tabla: la categoría 4 (Bebidas) se surte de tres proveedores distintos, mientras que la 6 (Complementos) depende de uno solo, y ese único proveedor —el 5, EcoNordic— es precisamente el que está inactivo. Sin DISTINCT habrías tenido que leer 20 filas para llegar a la misma conclusión.

Si de verdad quieres "un país por fila y algo de sus ciudades", DISTINCT no es la herramienta: necesitas agrupar, que es GROUP BY (lección 04-05). La diferencia conceptual, para tenerla clara desde ya:

Herramienta Qué hace Lección
DISTINCT Elimina filas repetidas del resultado tal cual está 02-04
GROUP BY Colapsa grupos de filas en una sola y permite calcular sobre cada grupo (contar, sumar, promediar) 04-05

  1. Dónde encaja DISTINCT en el orden lógico

DISTINCT se aplica después de la proyección del SELECT y antes de ORDER BY. Esto es coherente: solo se pueden comparar filas duplicadas una vez que se sabe qué columnas contienen.

flowchart LR
    A["1 · FROM<br/>clientes<br/>15 filas"] --> B["2 · WHERE<br/>filtra filas"]
    B --> C["3 · SELECT<br/>proyecta pais, ciudad"]
    C --> D["3b · DISTINCT<br/>elimina duplicados<br/>11 filas"]
    D --> E["4 · ORDER BY"]
    E --> F["5 · LIMIT"]

De ahí se deducen dos reglas que verás en acción enseguida:

Regla Consecuencia
WHERE se ejecuta antes que DISTINCT Primero se filtra, luego se deduplica. Nunca al revés
ORDER BY se ejecuta después que DISTINCT Solo puedes ordenar por columnas que hayan sobrevivido a la proyección

  1. DISTINCT combinado con WHERE y con ORDER BY

5.1. Con WHERE

SELECT DISTINCT ciudad
FROM clientes
WHERE pais = 'España';
ciudad
Valencia
Castellón
Madrid
Barcelona
Alicante
Sevilla
Zaragoza

7 ciudades españolas. El orden es: FROM trae las 15 filas → WHERE deja 11 → SELECT proyecta ciudadDISTINCT reduce a 7.

5.2. Con ORDER BY

SELECT DISTINCT pais
FROM clientes
ORDER BY pais;
pais
España
Francia
Portugal

Ahora el orden sí está garantizado (alfabético). ORDER BY es la lección siguiente; aquí lo usamos solo para hacer legibles los resultados.

5.3. La restricción: solo puedes ordenar por lo que hayas seleccionado

Prueba esto:

SELECT DISTINCT pais
FROM clientes
ORDER BY ciudad;
ERROR:  for SELECT DISTINCT, ORDER BY expressions must appear in select list
LINE 3: ORDER BY ciudad;
                 ^

El mensaje es explícito y la razón es lógica, no arbitraria. Después del DISTINCT solo quedan tres filas: España, Portugal y Francia. La fila España procede de once filas originales con once ciudades distintas. ¿Por cuál de las once habría que ordenarla? La pregunta no tiene respuesta, así que PostgreSQL se niega a inventarse una.

La regla, memorizable: con SELECT DISTINCT, todo lo que aparezca en ORDER BY debe aparecer también en la lista del SELECT.

Si lo que querías era ordenar los países por algún criterio derivado de las ciudades, necesitas GROUP BY y una función de agregación (módulo 4).

Un caso frecuente que también falla por esto: ordenar por una columna que no proyectas.

-- ⚠️ ERROR
SELECT DISTINCT categoria_id FROM productos ORDER BY precio;

Mismo mensaje. Y si la "arreglas" añadiendo precio al SELECT, cambias la pregunta: pasarías de "categorías distintas" (6 filas) a "combinaciones distintas de categoría y precio" (20 filas, porque casi todos los precios son únicos). Añadir columnas al SELECT debilita el DISTINCT.

  1. COUNT(DISTINCT columna): un anticipo del módulo 4

Muchas veces no quieres la lista de valores distintos, sino cuántos hay. Para eso se combina DISTINCT con la función de agregación COUNT:

SELECT COUNT(*)               AS filas,
       COUNT(ciudad)          AS ciudades_no_nulas,
       COUNT(DISTINCT ciudad) AS ciudades_distintas,
       COUNT(DISTINCT pais)   AS paises_distintos
FROM clientes;
filas ciudades_no_nulas ciudades_distintas paises_distintos
15 15 11 3

Fíjate en la diferencia entre las tres variantes de COUNT:

Expresión Qué cuenta
COUNT(*) Filas, sin mirar valores
COUNT(columna) Valores no nulos de esa columna
COUNT(DISTINCT columna) Valores distintos y no nulos

Aquí COUNT(ciudad) coincide con COUNT(*) porque en TiendaVerde ningún cliente tiene la ciudad a nulo, pero la columna admite nulos y en otra base de datos la diferencia sería visible.

No profundizamos más: COUNT, SUM, AVG, MIN y MAX son la lección 04-04, y la agrupación por categorías, la 04-05. Lo dejamos aquí simplemente porque es la aplicación más frecuente de DISTINCT en el trabajo real de análisis.

  1. DISTINCT ON: la extensión de PostgreSQL

PostgreSQL añade una variante que no está en el estándar SQL y que es enormemente útil: DISTINCT ON (columnas) conserva la primera fila de cada grupo de valores, según el orden que tú indiques.

Problema: el producto más caro de cada categoría.

SELECT DISTINCT ON (categoria_id)
       categoria_id,
       id,
       nombre,
       precio
FROM productos
ORDER BY categoria_id, precio DESC;
categoria_id id nombre precio
1 1 Aceite de oliva virgen extra 500 ml 12.50
2 6 Crema facial de aloe vera 50 ml 18.90
3 13 Velas de cera de soja (pack 2) 13.75
4 15 Té verde matcha ceremonial 30 g 22.00
5 19 Desodorante natural en barra 50 g 7.80
6 20 Cápsulas de espirulina 120 uds 16.40

Seis filas, una por categoría, con el producto más caro de cada una. Esto con DISTINCT a secas es imposible.

Cómo funciona, paso a paso:

  1. ORDER BY categoria_id, precio DESC ordena todas las filas: primero agrupadas por categoría, y dentro de cada categoría, de más caro a más barato.
  2. DISTINCT ON (categoria_id) recorre ese resultado ordenado y se queda con la primera fila de cada valor de categoria_id, descartando el resto.

De ahí sale la regla de oro:

Las columnas de DISTINCT ON (...) deben ser las primeras del ORDER BY, y en el mismo orden. Si no lo son, PostgreSQL da error; y si el ORDER BY no desempata bien lo que viene después, la fila elegida dentro de cada grupo es impredecible.

Si cambias precio DESC por precio, obtienes el producto más barato de cada categoría:

SELECT DISTINCT ON (categoria_id)
       categoria_id, id, nombre, precio
FROM productos
ORDER BY categoria_id, precio;
categoria_id id nombre precio
1 5 Tomate triturado ecológico 400 g 1.95
2 9 Bálsamo labial de caléndula 15 ml 4.60
3 11 Estropajo vegetal de luffa (pack 3) 5.50
4 14 Infusión de manzanilla ecológica 20 uds 3.25
5 18 Cepillo de dientes de bambú 3.50
6 20 Cápsulas de espirulina 120 uds 16.40

El patrón "la fila más X de cada grupo" (el último pedido de cada cliente, la reseña más reciente de cada producto, el precio más alto de cada categoría) es uno de los más pedidos en el mundo real, y DISTINCT ON lo resuelve en tres líneas.

Portabilidad:

Motor Cómo se hace
PostgreSQL DISTINCT ON (...) con el ORDER BY adecuado
Estándar SQL / MySQL 8 / SQL Server / Oracle Función de ventana: ROW_NUMBER() OVER (PARTITION BY categoria_id ORDER BY precio DESC) y quedarse con la fila 1
SQLite Función de ventana (desde 3.25) o el truco de MAX() con GROUP BY
MySQL 5.7 Subconsulta correlacionada (módulo 7)

La forma portable con funciones de ventana se estudia en la lección 10-03, y es la que deberás usar si tu SQL tiene que funcionar fuera de PostgreSQL. Mientras trabajes con PostgreSQL, DISTINCT ON es más corto y suele ser más rápido.

  1. El coste de DISTINCT y cuándo delata un error

DISTINCT no es gratis. Para saber si una fila está repetida, PostgreSQL tiene que comparar todas las filas entre sí, y lo hace de una de estas dos formas:

Estrategia Cómo funciona Coste
HashAggregate Construye una tabla hash con las filas ya vistas Rápida, pero consume memoria proporcional al número de valores distintos
Sort + Unique Ordena todas las filas y elimina las contiguas iguales Requiere ordenar todo el conjunto; si no cabe en memoria, escribe en disco

Con 15 filas es instantáneo. Con diez millones de filas y una columna de texto largo, un DISTINCT innecesario puede convertir una consulta de 50 ms en una de 30 segundos. Podrás verlo tú mismo con EXPLAIN en el módulo 8.

Y hay algo más importante que el coste: un DISTINCT inesperado suele ser el síntoma de una consulta mal planteada, no la solución. El caso típico llega en el módulo 3:

-- Anticipo del módulo 3: "clientes que han hecho algún pedido"
SELECT c.nombre, c.apellidos
FROM clientes AS c
JOIN pedidos AS p ON p.cliente_id = c.id;

Esa consulta devuelve 20 filas y no 12, porque Lucía Martínez tiene tres pedidos (1, 5 y 15) y aparece tres veces. El reflejo natural es añadir DISTINCT y quedarse tranquilo. Pero el DISTINCT no arregla nada: oculta el hecho de que la unión ha multiplicado las filas. Si mañana añades una columna al SELECT —por ejemplo p.fecha_pedido—, las filas vuelven a duplicarse y el DISTINCT deja de servir.

La lista de comprobación cuando te descubras escribiendo DISTINCT:

  1. ¿Hay duplicados de verdad, o los está creando mi consulta? Si es lo segundo, el problema está en la unión, no en la proyección.
  2. ¿Lo que quiero es "valores distintos" o "un resultado por grupo"? Si es lo segundo, es GROUP BY (04-05) o DISTINCT ON (sección 7).
  3. ¿Quiero comprobar existencia? Entonces la herramienta correcta es EXISTS (lección 07-03), que no multiplica filas y por tanto no necesita deduplicar.
  4. ¿Estoy deduplicando por columnas que no necesito? Quitar del SELECT una columna innecesaria puede hacer que el DISTINCT sobre.

DISTINCT es perfectamente legítimo para lo que hemos hecho en esta lección: preguntar "¿qué valores distintos hay en esta columna?". Lo sospechoso es usarlo como parche.

Errores Comunes y Consejos

  • Creer que DISTINCT columna1, columna2 deduplica solo por la primera. Deduplica por la combinación completa. Es el malentendido número uno.
  • Escribir DISTINCT(columna). Funciona, pero hace pensar que DISTINCT es una función que se aplica a esa columna. No lo es. Escribe DISTINCT columna1, columna2.
  • Esperar que DISTINCT ordene. No ordena. Si necesitas orden, ORDER BY.
  • Ordenar por una columna que no está en un SELECT DISTINCT. ORDER BY expressions must appear in select list. Y "arreglarlo" añadiendo la columna cambia la pregunta.
  • Añadir columnas y no darse cuenta de que el DISTINCT deja de servir. Cada columna nueva puede multiplicar las filas del resultado.
  • Usar DISTINCT para tapar duplicados creados por un JOIN. Corrige la consulta, no el síntoma.
  • Olvidar que los NULL se agrupan. DISTINCT devuelve una sola fila con NULL, aunque haya cien.
  • Usar DISTINCT ON sin el ORDER BY correcto. La fila que se conserva de cada grupo es entonces impredecible: hoy una, mañana otra.
  • Consejo: para contar valores únicos, COUNT(DISTINCT col) en lugar de traerte la lista y contarla a mano.
  • Consejo: usa DISTINCT como herramienta de exploración. SELECT DISTINCT estado FROM pedidos; es la forma más rápida de saber qué valores contiene realmente una columna, incluidos los que no deberían estar ahí.
  • Consejo: si DISTINCT es lento, mira el plan. EXPLAIN (módulo 8) te dirá si está ordenando en disco.

Ejercicios

Ejercicio 1

Marketing quiere saber desde qué ciudades se ha comprado en Portugal y Francia. Escribe una consulta que devuelva las combinaciones distintas de pais y ciudad de los clientes que no sean de España, ordenadas por país y ciudad. Explica por qué el resultado tiene el número de filas que tiene.

Ejercicio 2

Un compañero escribe esta consulta para saber cuántos métodos de pago distintos se usan y se sorprende del resultado:

SELECT DISTINCT metodo_pago, estado
FROM pedidos;

Explica qué devuelve realmente, cuántas filas y por qué no responde a su pregunta. Escribe después las dos consultas correctas: la que da la lista de métodos y la que da el número.

Ejercicio 3

Usando DISTINCT ON, obtén el pedido más reciente de cada cliente que haya comprado: cliente_id, id del pedido, fecha_pedido y estado. Explica por qué el resultado tiene 12 filas y no 15, y qué papel juega el ORDER BY.

Soluciones

Solución 1

SELECT DISTINCT pais, ciudad
FROM clientes
WHERE pais <> 'España'
ORDER BY pais, ciudad;
pais ciudad
Francia Lyon
Francia París
Portugal Lisboa
Portugal Oporto

4 filas. El razonamiento sigue el orden lógico de ejecución:

  1. FROM clientes → 15 filas.
  2. WHERE pais <> 'España' → quedan 4 (los clientes 7, 8, 9 y 10). Aquí no hay problema de nulos porque pais es NOT NULL; si admitiera nulos, esos clientes se habrían perdido silenciosamente, como viste en 02-03.
  3. SELECT pais, ciudad → proyecta dos columnas de esas 4 filas.
  4. DISTINCT → busca combinaciones repetidas... y no hay ninguna, porque los cuatro clientes extranjeros viven en cuatro ciudades diferentes.

Es decir, en este caso concreto DISTINCT no elimina nada. Eso no lo hace inútil: garantiza que si mañana se registra un segundo cliente en Lisboa, el informe seguirá siendo correcto.

Solución 2

La consulta del compañero devuelve las combinaciones distintas de método de pago y estado:

metodo_pago estado
tarjeta entregado
tarjeta cancelado
tarjeta enviado
tarjeta pagado
transferencia entregado
transferencia pagado
paypal entregado
paypal enviado
contrareembolso entregado
contrareembolso pendiente

10 filas. tarjeta aparece cuatro veces, una por cada estado en el que hay algún pedido pagado con tarjeta. No responde a "cuántos métodos de pago distintos hay" porque DISTINCT deduplica la pareja completa, y las parejas son distintas aunque compartan el método.

Las dos consultas correctas:

-- La lista de métodos
SELECT DISTINCT metodo_pago
FROM pedidos
ORDER BY metodo_pago;
metodo_pago
contrareembolso
paypal
tarjeta
transferencia
-- El número de métodos
SELECT COUNT(DISTINCT metodo_pago) AS metodos_usados
FROM pedidos;
metodos_usados
4

La moraleja: cada columna que añades al SELECT puede multiplicar las filas del resultado, porque debilita la condición de igualdad que usa DISTINCT. Antes de añadir una columna a un SELECT DISTINCT, pregúntate si sigue respondiendo a tu pregunta.

Solución 3

SELECT DISTINCT ON (cliente_id)
       cliente_id,
       id,
       fecha_pedido,
       estado
FROM pedidos
ORDER BY cliente_id, fecha_pedido DESC;
cliente_id id fecha_pedido estado
1 15 2025-12-02 entregado
2 11 2025-09-09 entregado
3 3 2025-04-02 entregado
4 16 2025-12-19 enviado
5 18 2026-01-27 pagado
6 19 2026-02-09 pagado
7 17 2026-01-13 enviado
8 9 2025-07-15 entregado
9 20 2026-02-21 pendiente
10 12 2025-10-01 entregado
11 13 2025-10-22 entregado
12 14 2025-11-14 entregado

12 filas y no 15. El motivo está en los huecos deliberados del conjunto de datos: los clientes 13, 14 y 15 no han hecho ningún pedido, así que no aparecen en la tabla pedidos y no hay nada que agrupar para ellos. Una consulta sobre pedidos solo puede hablar de clientes que han pedido; para listar también a los que nunca compraron hace falta combinar las dos tablas con un LEFT JOIN, que es exactamente el contenido de la lección 03-03.

El papel del ORDER BY es doble y ambos son imprescindibles:

  • cliente_id primero porque es la columna del DISTINCT ON: PostgreSQL exige que coincidan, ya que necesita las filas de cada cliente juntas para quedarse con una.
  • fecha_pedido DESC después porque determina cuál de las filas de cada cliente sobrevive: la primera del grupo, es decir, la de fecha más alta.

Si escribieras ORDER BY cliente_id, fecha_pedido (ascendente), obtendrías el primer pedido de cada cliente. Y si omitieras la segunda columna del ORDER BY, la fila elegida dentro de cada cliente sería la que el motor devolviera primero, que puede cambiar entre ejecuciones.

Comprobación rápida: Lucía Martínez (cliente 1) tiene los pedidos 1, 5 y 15, con fechas 2025-03-04, 2025-05-07 y 2025-12-02. Ha salido el 15, el más reciente. Correcto.

Conclusión

Ya sabes tratar los duplicados:

  • Las filas repetidas no vienen de los datos, sino de la proyección: al quitar columnas, lo que queda se repite. SQL trabaja con multiconjuntos y no las elimina si no se lo pides.
  • DISTINCT se escribe justo después de SELECT y elimina filas repetidas comparando la combinación completa de columnas proyectadas, no solo la primera.
  • Se aplica después de la proyección y antes de ORDER BY, de donde sale la restricción de que todo lo que ordenes debe estar en el SELECT.
  • Los NULL se colapsan en una sola fila, por excepción a la regla general de los nulos.
  • COUNT(DISTINCT columna) cuenta valores únicos y es la aplicación más habitual en análisis de datos; las agregaciones completas llegan en el módulo 4.
  • DISTINCT ON (...) es una extensión de PostgreSQL que devuelve la primera fila de cada grupo según el ORDER BY, y resuelve en tres líneas el patrón "la fila más reciente / más cara de cada X". Fuera de PostgreSQL se hace con funciones de ventana (módulo 10).
  • DISTINCT cuesta (ordenar o construir una tabla hash) y, cuando aparece por sorpresa, suele delatar una consulta mal planteada más que resolver un problema.

En la siguiente lección, Ordenando datos con ORDER BY, dejarás de aceptar el orden que el motor tenga a bien darte. Verás cómo ordenar por una o varias columnas, cómo se resuelven los empates, cómo ordenar por alias y por expresiones calculadas, dónde coloca PostgreSQL los valores nulos (y por qué MySQL los pone en el otro extremo) y por qué la letra Ñ puede aparecer donde no esperas.

Curso de SQL

Módulo 1: Introducción a SQL

Módulo 2: Consultas básicas de SQL

Módulo 3: Trabajando con múltiples tablas

Módulo 4: Filtrado avanzado de datos

Módulo 5: Manipulación de datos

Módulo 6: Funciones avanzadas de SQL

Módulo 7: Subconsultas y consultas anidadas

Módulo 8: Índices y optimización de rendimiento

Módulo 9: Transacciones y concurrencia

Módulo 10: Temas avanzados

Módulo 11: SQL en la práctica

Módulo 12: Proyecto final

© Copyright 2026. Todos los derechos reservados