INTERSECT

El operador INTERSECT devuelve las filas que aparecen en ambas consultas. Es la intersección de conjuntos: solo se mantienen las filas que existen tanto en el primer SELECT como en el segundo.

MySQL soporta INTERSECT desde la versión 8.0.31. En versiones anteriores, puedes conseguir el mismo resultado con INNER JOIN o con IN y subconsultas.

Sintaxis

SELECT columnas FROM tabla1
INTERSECT
SELECT columnas FROM tabla2;

Al igual que con UNION, ambas consultas deben devolver el mismo número de columnas. INTERSECT elimina duplicados automáticamente (se comporta como INTERSECT DISTINCT). Si necesitas mantener duplicados, puedes usar INTERSECT ALL.

Productos premium que son más vendidos

Los productos que tienen simultáneamente las etiquetas "premium" y "más vendido":

SELECT p.nombre, p.precio
FROM productos p
JOIN etiquetas_producto ep ON p.id = ep.producto_id
WHERE ep.etiqueta = 'premium'
 
INTERSECT
 
SELECT p.nombre, p.precio
FROM productos p
JOIN etiquetas_producto ep ON p.id = ep.producto_id
WHERE ep.etiqueta = 'más vendido';
nombreprecio
iPhone 15 Pro1299.99

De los 4 productos premium y los 5 más vendidos, solo el iPhone 15 Pro tiene ambas etiquetas. El INTERSECT descarta los productos que solo aparecen en uno de los dos conjuntos.

Productos vendidos y reseñados

Productos que se han vendido al menos una vez y que también tienen al menos una reseña:

SELECT DISTINCT p.nombre
FROM productos p
JOIN detalle_pedidos dp ON p.id = dp.producto_id
 
INTERSECT
 
SELECT DISTINCT p.nombre
FROM productos p
JOIN resenas r ON p.id = r.producto_id
 
ORDER BY nombre
LIMIT 8;
nombre
ASUS ROG Zephyrus
Cable USB-C a Lightning
Camiseta algodón básica
Clean Code
Escritorio ajustable
Esterilla yoga premium
Google Pixel 8
iPhone 15 Pro

Solo los productos que aparecen en ambas tablas (detalle_pedidos y resenas) pasan el filtro. Los productos que se vendieron pero nadie reseñó, o que fueron reseñados sin haberse vendido, quedan fuera.

Clientes compradores y opinadores

Clientes que han realizado al menos un pedido y han dejado al menos una reseña:

SELECT cl.nombre, cl.apellidos
FROM clientes cl
JOIN pedidos p ON cl.id = p.cliente_id
 
INTERSECT
 
SELECT cl.nombre, cl.apellidos
FROM clientes cl
JOIN resenas r ON cl.id = r.cliente_id
 
ORDER BY nombre;
nombreapellidos
AnaMartínez Ruiz
AndrésVega Romero
CarlosRodríguez Martín
DavidSánchez Moreno
IsabelGil Molina
JavierMoreno Díaz
LauraLópez Sánchez
LucíaDíaz Hernández
MaríaGarcía López
MiguelHernández Torres
PedroFernández Castro
SaraTorres Vega

12 clientes han hecho ambas cosas: comprar y opinar. Los clientes que solo compraron pero no dejaron reseña (como Carmen, Elena, etc.) y Diego (que reseñó un producto pero nunca compró) quedan excluidos.

Alternativa con INNER JOIN

En versiones de MySQL anteriores a 8.0.31 (o cuando prefieras mayor compatibilidad), puedes emular INTERSECT con un INNER JOIN:

-- Equivalente al INTERSECT de productos premium + más vendidos
SELECT DISTINCT p.nombre, p.precio
FROM productos p
JOIN etiquetas_producto ep1 ON p.id = ep1.producto_id
JOIN etiquetas_producto ep2 ON p.id = ep2.producto_id
WHERE ep1.etiqueta = 'premium'
  AND ep2.etiqueta = 'más vendido';

Otra alternativa es usar IN con una subconsulta:

SELECT p.nombre, p.precio
FROM productos p
JOIN etiquetas_producto ep ON p.id = ep.producto_id
WHERE ep.etiqueta = 'premium'
  AND p.id IN (
      SELECT producto_id
      FROM etiquetas_producto
      WHERE etiqueta = 'más vendido'
  );

Las tres formas producen el mismo resultado. INTERSECT es más legible cuando las dos consultas tienen estructuras muy diferentes. INNER JOIN o IN pueden ser más intuitivos cuando la relación entre los conjuntos es directa.

INTERSECT con múltiples consultas

Puedes encadenar varios INTERSECT:

-- Productos que tienen las tres etiquetas: premium, más vendido y novedad
SELECT producto_id FROM etiquetas_producto WHERE etiqueta = 'premium'
INTERSECT
SELECT producto_id FROM etiquetas_producto WHERE etiqueta = 'más vendido'
INTERSECT
SELECT producto_id FROM etiquetas_producto WHERE etiqueta = 'novedad';
producto_id
1

El producto 1 (iPhone 15 Pro) es el único que tiene las tres etiquetas simultáneamente.

Practica con INTERSECT

Usa el editor para encontrar elementos comunes entre consultas:

Simulador SQL
Ctrl+Enter para ejecutar

En el siguiente artículo veremos EXCEPT, que devuelve las filas de la primera consulta que no aparecen en la segunda.

Escrito por Eduardo Lázaro