Ir al contenido principal
¿Te ayudamos?
oposiciones

SQL UNION, INTERSECT y EXCEPT: 8 ejercicios

12 min de lectura

Practica SQL con ocho ejercicios resueltos: UNION y UNION ALL, INTERSECT, EXCEPT, duplicados, NULL y COUNT. Consultas comprobadas en SQLite.

Para resolver ejercicios de SQL sobre UNION, INTERSECT y EXCEPT, necesitas seguir las filas de cada rama y comprobar qué ocurre con sus repeticiones. Reconocer el nombre del operador no basta cuando aparecen NULL, agregados o una segunda columna que cambia la identidad de la fila.

Esta práctica reúne ocho preguntas originales, cuatro opciones por pregunta y soluciones razonadas. Las consultas se han comprobado en SQLite 3.46.1. El último ejercicio contiene un error intencionado: detectar por qué falla también forma parte del trabajo. Son datos ficticios y ejercicios de entrenamiento; no proceden de un examen oficial ni presuponen el gestor de una oposición concreta.

Datos comunes: dos listas con repeticiones y nulos

Crea una base de datos de prácticas vacía y ejecuta una vez esta inicialización. Si repites el bloque en la misma base, las tablas ya existirán. Para empezar de nuevo, utiliza otra base de prácticas vacía.

CREATE TABLE list_a (n INTEGER);
CREATE TABLE list_b (n INTEGER);
INSERT INTO list_a (n) VALUES (1), (2), (2), (NULL);
INSERT INTO list_b (n) VALUES (2), (3), (NULL), (NULL);
TablaFilas de la columna n, con sus repeticiones
list_a1, 2, 2, NULL
list_b2, 3, NULL, NULL

Cada tabla tiene cuatro filas. En total hay ocho, de las cuales cinco contienen un número y tres contienen NULL. No hemos declarado una clave primaria: las repeticiones son intencionadas. La tabla anterior enumera contenido, no garantiza el orden físico en que lo devolverá cualquier consulta.

Todos los ejercicios parten de esos mismos datos. Las ocho consultas no modifican las tablas; no debes acumular resultados de una pregunta dentro de la siguiente. Usa la misma inicialización para predecir cada salida antes de abrir su solución.

Qué revisar antes de elegir una respuesta

Empieza por las columnas. Las dos ramas de una consulta compuesta deben entregar la misma cantidad. Después escribe sus filas: con UNION ALL conservarás las apariciones; con UNION eliminarás duplicados; con INTERSECT buscarás filas presentes en ambos resultados; con EXCEPT conservarás las de la izquierda ausentes de la derecha. En SQLite, los dos últimos también eliminan duplicados.

Compara la fila completa. Si seleccionas número y origen, dos filas con el mismo número pueden ser distintas. Trata los nulos según la operación concreta: su comparación para duplicados en estas consultas compuestas no se razona como una condición ordinaria = NULL. Ordena cuando el resultado deba ser una secuencia: el ORDER BY final se aplica al conjunto compuesto.

La documentación oficial de SELECT de SQLite, apartados 3 y 4, recoge estas reglas. Aquí trabajamos con enteros, nulos y dos etiquetas sencillas; no estudiamos conversiones entre tipos, combinaciones de tres operadores ni comparaciones de texto con distintas reglas de intercalación.

Ejercicio 1. UNION elimina repeticiones

¿Qué secuencia de valores devuelve esta consulta, de arriba abajo?

SELECT n FROM list_a WHERE n IS NOT NULL
UNION
SELECT n FROM list_b WHERE n IS NOT NULL
ORDER BY n;

A. 1, 2, 2, 2, 3. B. 1, 2, 3. C. 2. D. 1, 3.

Ver solución del ejercicio 1

Correcta: B. Las filas no nulas de la primera rama son 1, 2 y 2; las de la segunda son 2 y 3. UNION deja una sola aparición de cada fila: 1, 2 y 3. El duplicado de 2 dentro de list_a también desaparece; la eliminación no se limita a coincidencias entre tablas.

La opción A conserva las cinco apariciones y correspondería al siguiente ejercicio. C confunde unión con intersección; D elimina el valor común como si se pidieran únicamente valores exclusivos. El ORDER BY n final permite dar la respuesta como secuencia ascendente. No atribuyas esa garantía de orden a la palabra UNION.

Ejercicio 2. UNION ALL conserva cada aparición

Con los mismos filtros, ¿qué secuencia se obtiene al usar UNION ALL?

SELECT n FROM list_a WHERE n IS NOT NULL
UNION ALL
SELECT n FROM list_b WHERE n IS NOT NULL
ORDER BY n;

A. 1, 2, 3. B. 2, 2, 2. C. 1, 2, 2, 3. D. 1, 2, 2, 2, 3.

Ver solución del ejercicio 2

Correcta: D. Hay tres filas no nulas a la izquierda y dos a la derecha: cinco en total. El valor 2 aparece dos veces en list_a y una en list_b, por lo que debe verse tres veces. UNION ALL conserva todas esas apariciones; la ordenación posterior no elimina ninguna.

A aplica por error la eliminación de duplicados de UNION. B conserva solo el valor compartido. C pierde uno de los tres doses: es el fallo de contar valores distintos dentro de una rama antes de combinarla. Escribe las cinco filas antes de ordenar y podrás localizar la aparición olvidada. Esta comparación estudia resultados; no mide rendimiento ni demuestra que una consulta sea siempre más rápida.

Ejercicio 3. INTERSECT también compara los NULL

¿Qué filas contiene el resultado? Las opciones indican contenido y multiplicidad, sin prometer orden.

SELECT n FROM list_a
INTERSECT
SELECT n FROM list_b;

A. Dos filas: 2 y NULL, una de cada. B. Una fila: 2. C. Tres filas: 2, 2 y NULL. D. Cuatro filas: 1, 2, 3 y NULL.

Ver solución del ejercicio 3

Correcta: A. El 2 está presente en ambas ramas y NULL también. En la comparación de filas de una consulta compuesta de SQLite, los nulos se consideran iguales entre sí a estos efectos. INTERSECT entrega las filas comunes sin duplicados: una con 2 y otra con NULL.

B descarta el nulo por trasladar a esta operación una regla de las comparaciones con =. C arrastra una repetición de 2 que la intersección elimina. D describe los valores de una unión. La consulta no contiene ORDER BY: aunque una ejecución muestre primero el nulo, esa observación no permite exigir siempre ese orden. El cliente puede representar el nulo como celda vacía; aquí escribimos NULL para identificarlo.

Ejercicio 4. EXCEPT tiene una dirección

¿Qué fila devuelve la diferencia escrita a continuación?

SELECT n FROM list_a
EXCEPT
SELECT n FROM list_b;

A. 3. B. 2. C. 1. D. Ninguna fila.

Ver solución del ejercicio 4

Correcta: C. Se buscan filas de list_a que no estén en list_b. El 1 cumple esa condición. El 2 y el nulo aparecen también a la derecha y quedan excluidos. La repetición de 2 a la izquierda no crea una unidad sobrante: EXCEPT no realiza aquí una resta de cantidades de apariciones.

A invierte la dirección y responde a list_b menos list_a. B confunde diferencia con valor común. D olvida que el 1 solo está a la izquierda. Anota siempre «izquierda menos derecha» antes de resolver. El resultado tiene una única fila, de modo que en este caso no hay varias filas cuyo orden deba precisarse.

Ejercicio 5. Contar filas después de UNION ALL

¿Qué pareja (rows_total, rows_non_null) devuelve el agregado?

SELECT COUNT(*) AS rows_total, COUNT(n) AS rows_non_null
FROM (
  SELECT n FROM list_a
  UNION ALL
  SELECT n FROM list_b
);

A. (8, 8). B. (8, 5). C. (5, 5). D. (4, 3).

Ver solución del ejercicio 5

Correcta: B. La subconsulta conserva las ocho filas originales, incluidos los tres nulos: uno de list_a y dos de list_b. COUNT(*) cuenta las ocho filas; COUNT(n) cuenta los cinco valores no nulos. La consulta exterior produce una fila con los dos recuentos.

A cuenta los nulos como valores no nulos. C los descarta antes de calcular ambos agregados, aunque no hay un filtro que lo haga. D anticipa la eliminación de duplicados del siguiente ejercicio. Separa dos decisiones: qué filas entrega la subconsulta y qué cuenta cada agregado sobre ellas. La referencia oficial de COUNT en SQLite distingue expresamente ambos recuentos.

Ejercicio 6. Contar después de eliminar duplicados

¿Qué pareja (rows_total, rows_non_null) queda al cambiar únicamente UNION ALL por UNION?

SELECT COUNT(*) AS rows_total, COUNT(n) AS rows_non_null
FROM (
  SELECT n FROM list_a
  UNION
  SELECT n FROM list_b
);

A. (8, 5). B. (3, 3). C. (4, 4). D. (4, 3).

Ver solución del ejercicio 6

Correcta: D. La subconsulta contiene cuatro filas distintas a estos efectos: 1, 2, 3 y un nulo. COUNT(*) da 4 y COUNT(n) da 3. Primero se determina el resultado de la unión y después se cuentan sus filas o sus valores no nulos.

A conserva el resultado anterior como si no hubiera cambiado el operador. B elimina por completo la fila nula. C la incluye correctamente como fila, pero después la cuenta también como valor no nulo. El tratamiento de duplicados no transforma el nulo en cero ni en texto. La nota de SQLite sobre NULL describe su eliminación de duplicados en UNION; no debe convertirse en una afirmación de que cualquier comparación con nulos funciona igual.

Ejercicio 7. La fila completa decide el duplicado

¿Qué secuencia de parejas (n, origin) devuelve esta consulta?

SELECT n, 'A' AS origin FROM list_a WHERE n IS NOT NULL
UNION
SELECT n, 'B' AS origin FROM list_b WHERE n IS NOT NULL
ORDER BY n, origin;

A. (1, A), (2, A), (2, B), (3, B). B. (1, A), (2, A), (3, B). C. (1, A), (2, A), (2, A), (2, B), (3, B). D. (2, A), (2, B).

Ver solución del ejercicio 7

Correcta: A. Las dos apariciones de (2, A) son filas iguales y quedan en una. En cambio, (2, A) y (2, B) difieren en la segunda columna y se conservan las dos. La unión compara las filas proyectadas completas, no únicamente su primera columna.

B elimina indebidamente una pareja por repetir el número 2. C conserva el duplicado completo de la rama A, como haría UNION ALL. D se queda solo con el número compartido, aunque no se pide una intersección. El ORDER BY n, origin final ordena primero por número y después por origen; con estas etiquetas, A precede a B. Añadir una etiqueta puede cambiar qué filas se consideran duplicadas: no es una columna decorativa para esta operación.

Ejercicio 8. Las ramas necesitan el mismo número de columnas

¿Qué ocurre al ejecutar esta consulta en SQLite con las tablas iniciales?

SELECT n FROM list_a
UNION ALL
SELECT n, 0 AS flag FROM list_b;

A. Devuelve ocho filas y añade NULL a la columna que falta. B. Devuelve ocho filas e ignora flag. C. Produce un error por distinto número de columnas. D. Devuelve cuatro filas porque UNION ALL elimina duplicados.

Ver solución del ejercicio 8

Correcta: C. La primera rama selecciona una columna y la segunda dos. SQLite rechaza esta consulta compuesta: las ramas deben devolver el mismo número de columnas. El error se produce antes de obtener una salida de filas; no hay que intentar contar una tabla de resultados inexistente.

A inventa un relleno automático; B inventa un descarte automático. D suma otro error al atribuir eliminación de duplicados a UNION ALL. Para construir una consulta válida hay que decidir qué columnas se desean y escribir ramas con la misma cantidad. Igualar esa cantidad corrige este defecto concreto; no supone haber validado cualquier otro aspecto de una consulta distinta ni la compatibilidad de todos los gestores.

Corrige el razonamiento, además de la letra

La clave es 1B, 2D, 3A, 4C, 5B, 6D, 7A y 8C. Para cada fallo, escribe el resultado intermedio que habías previsto. Si elegiste cinco filas en el primer caso, revisa duplicados; si obtuviste tres en el segundo, has eliminado apariciones que debían mantenerse. Si fallaste los recuentos, separa la subconsulta del agregado exterior.

En los casos 3 y 4 interesa el contenido, sin imponer una ordenación de varias filas que el código no solicita. En el 7 debes comparar parejas completas. En el 8 detente en la estructura de las ramas antes de intentar aplicar el operador. Esa clasificación permite repetir la pregunta que trabaja tu error sin convertir la sesión en una simple memorización de letras.

Para ampliar la práctica, continúa con los ejercicios SQL de JOIN, NULL y GROUP BY. Trabajan relaciones entre filas y recuentos con datos distintos. Después puedes estudiar los casos de claves primarias y foráneas para distinguir el resultado de una consulta de las restricciones que admiten o rechazan datos.

Relación con el temario informático

El Pack Técnico/a Auxiliar Informático Cádiz 2026 incluye materia sobre composición de consultas y operaciones de conjuntos. Es un producto de pago; su ficha detalla el alcance del material. Esta práctica sirve como apoyo para razonar resultados, sin atribuir a la convocatoria el uso de SQLite ni sustituir el programa oficial.

Cuando cambies de material o de gestor, comprueba la sintaxis correspondiente. Aquí se utiliza expresamente EXCEPT en SQLite. El objetivo verificable de la sesión es poder explicar cada fila conservada o eliminada y justificar el error del último caso con los datos y las consultas que tienes delante.

Practica posiciones, empates y particiones

Los ocho ejercicios de ROW_NUMBER, RANK y DENSE_RANK amplían la práctica con funciones de ventana en SQLite. Permiten distinguir numeración, empate, partición y orden de presentación, con datos ficticios y un caso de error intencionado.

Preguntas frecuentes

¿Qué diferencia hay entre UNION y UNION ALL?

En estos ejercicios de SQLite, UNION elimina filas duplicadas y UNION ALL conserva cada aparición. Por eso las dos primeras consultas devuelven tres y cinco filas, respectivamente.

¿UNION elimina duplicados mirando solo la primera columna?

No. Compara las filas seleccionadas completas. En el ejercicio 7, las parejas (2, A) y (2, B) se conservan porque difieren en la segunda columna.

¿Por qué NULL aparece una sola vez con UNION?

SQLite considera iguales entre sí los NULL al comparar filas para estas consultas compuestas. Esa regla de eliminación de duplicados no significa que una comparación ordinaria con = NULL resulte verdadera.

¿UNION garantiza que las filas salgan ordenadas?

No debes exigir un orden sin ORDER BY. En esta práctica, las preguntas que piden una secuencia de varias filas incluyen una ordenación final explícita.

¿Son preguntas oficiales y sirven igual para cualquier gestor?

Son ejercicios originales comprobados en SQLite 3.46.1. No son preguntas oficiales ni acreditan ejecución en otros motores. Si un enunciado fija gestor o versión, aplica sus reglas y su sintaxis.