MySQL关联子查询问题:查询全类别租片客户返回空结果
问题排查:找出租借过所有类别影片的客户SQL错误分析
表结构
rental (customer_id, inventory_id) inventory (inventory_id, film_id) film_category (film_id, category_id) category (category_id, name) -- 表中共有12个类别
需求与问题
需要找出至少租借过每个类别影片的客户,但编写的SQL返回0条结果,实际应有19条符合条件的数据。
错误SQL
SELECT customer_id FROM rental NATURAL JOIN( SELECT film_id FROM inventory NATURAL JOIN( SELECT f1.category_id FROM film_category AS f1 WHERE NOT EXISTS( (SELECT category_id FROM category) except (SELECT category_id FROM film_category AS f2 WHERE f2.film_id = f1.film_id) ) )AS T1)AS T2
错误原因
你的SQL逻辑完全偏离需求:内层子查询是在寻找单部影片覆盖所有12个类别的film_id,但现实中没有任何影片会属于所有类别,导致中间表T1、T2均为空,最终返回0条结果。这和“客户租借的影片集合覆盖所有类别”的需求完全不符。
正确SQL写法
方法一:分组统计法(高效直观)
SELECT r.customer_id FROM rental r JOIN inventory i ON r.inventory_id = i.inventory_id JOIN film_category fc ON i.film_id = fc.film_id GROUP BY r.customer_id HAVING COUNT(DISTINCT fc.category_id) = (SELECT COUNT(*) FROM category);
通过关联所有表,按客户分组后统计其租借过的唯一类别数量,当数量等于总类别数时,该客户符合要求。
方法二:关联子查询法(贴合关联子查询思路)
SELECT DISTINCT r.customer_id FROM rental r WHERE NOT EXISTS ( SELECT c.category_id FROM category c WHERE NOT EXISTS ( SELECT 1 FROM inventory i JOIN film_category fc ON i.film_id = fc.film_id WHERE i.inventory_id = r.inventory_id AND fc.category_id = c.category_id ) );
外层遍历所有客户,内层检查是否存在某个类别该客户从未租借过;若不存在这样的类别(即NOT EXISTS),则该客户满足条件。
内容的提问来源于stack exchange,提问作者catlover
相关产品推荐
相关产品推荐

