Consultas de división
Una consulta de división en SQL es una consulta que busca elementos en una tabla que no están relacionados con todos los elementos de otra tabla. Este tipo de consulta a menudo se utiliza cuando se trabaja con bases de datos relacionales y se quiere encontrar registros que no tengan correspondencia en otra tabla.
La estructura general de una consulta de división implica la selección de elementos de una tabla que no tienen una coincidencia con todos los elementos de otra tabla. Aquí hay un ejemplo conceptual:
Supongamos que tenemos dos tablas: empleados
y proyectos
. Queremos encontrar los empleados que no están asignados a todos los proyectos. Podríamos estructurar una consulta de división de la siguiente manera:
SELECT DISTINCT e.employee_id, e.employee_name
FROM employees e
WHERE NOT EXISTS (
SELECT p.project_id
FROM projects p
WHERE NOT EXISTS (
SELECT ep.project_id
FROM employee_projects ep
WHERE ep.employee_id = e.employee_id
AND ep.project_id = p.project_id
)
);
En este ejemplo:
- La tabla
employees
contiene información sobre los empleados. - La tabla
projects
contiene información sobre los proyectos. - La tabla
employee_projects
asocia empleados con proyectos.
La consulta selecciona empleados que no tienen una correspondencia con todos los proyectos.
Ten en cuenta que la estructura específica de la consulta de división puede variar según la base de datos y el esquema de tablas que estés utilizando. El ejemplo anterior es un enfoque general y puede necesitar ajustes según tu caso particular.
En el contexto de Sakila, consideremos un escenario en el que queremos encontrar clientes que no hayan alquilado todas las películas de una categoría específica. Aquí hay un ejemplo de consulta de división en Sakila para encontrar clientes que no han alquilado todas las películas de la categoría "Action":
SELECT c.customer_id, c.first_name, c.last_name
FROM customer c
WHERE NOT EXISTS (
SELECT f.film_id
FROM film f
WHERE f.category_id = (SELECT category_id FROM category WHERE name = 'Action')
AND NOT EXISTS (
SELECT r.rental_id
FROM rental r
WHERE r.customer_id = c.customer_id
AND r.inventory_id IN (SELECT i.inventory_id FROM inventory i WHERE i.film_id = f.film_id)
)
);
En este ejemplo:
- La tabla
customer
contiene información sobre los clientes. - La tabla
film
contiene información sobre las películas. - La tabla
category
contiene información sobre las categorías de películas. - La tabla
rental
contiene información sobre los alquileres. - La tabla
inventory
asocia películas con inventario.
La consulta busca clientes que no hayan alquilado todas las películas de la categoría "Action". Ten en cuenta que este es un ejemplo conceptual y puede variar según las especificaciones exactas de tu consulta.
-- ¿Qué actores no han trabajo en películas de rating 'R'? -- Los actores que SI han trabajado en películas de rating R -- Mostrar los que no son esos select distinct actor_id from actor join film_actor using(actor_id) join film using(film_id) where rating ='R'; -- Pues ahora los actores que no están en la anterior consulta select * from actor where actor_id not in ( select distinct actor_id from actor join film_actor using(actor_id) join film using(film_id) where rating ='R' ) -- ¿Qué actores no han trabajo en la categoría 'Música'? -- Los actores que SI han trabajado en películas de categoría Música -- Mostrar los que no son esos select actor_id from actor join film_actor using(actor_id) join film using(film_id) join film_category using(film_id) join category using(category_id) where name='Music'; -- Pues ahora los actores que no están en la anterior consulta select * from actor where actor_id not in ( select actor_id from actor join film_actor using(actor_id) join film using(film_id) join film_category using(film_id) join category using(category_id) where name='Music' )