数据库SQL查询卡住了

时间:2017-10-08 19:59:35

标签: mysql

我正在尝试撰写查询

我必须找到租用“喜剧”电影但尚未租借“戏剧”电影的客户的名字。 我写了以下查询,但我没有得到正确的结果。我认为没有租用“戏剧”部分在我的查询中不起作用。

SELECT DISTINCT CONCAT(customer.first_name,' ',customer.last_name) as Name
FROM  rental 
JOIN  inventory ON rental.inventory_id=inventory.inventory_id
JOIN  customer ON rental.customer_id=customer.customer_id
JOIN  film ON film.film_id=inventory.film_id
JOIN  film_category ON film_category.film_id=film.film_id
WHERE film_category.category_id=5 and 
      film_category.category_id<>7
ORDER by Name;

知道什么是错的吗?

3 个答案:

答案 0 :(得分:1)

如前面在其他答案中提到的,5不是7,但是在使用DISTINCT时也需要小心,因为你可能有两个同名的客户,而是使用group by子句。

处理此问题的最佳方法是子查询,CTE或临时表,具体取决于数据库的大小和您运行的MySQL的版本。这些对于MySQL来说是最少的工作,应该以最快的方式返回结果集。

您的10人入门是一个子查询:

SELECT CONCAT(customer.first_name,' ',customer.last_name) as Name
FROM  rental 
JOIN  inventory ON rental.inventory_id=inventory.inventory_id
JOIN  customer ON rental.customer_id=customer.customer_id
JOIN  film ON film.film_id=inventory.film_id
JOIN  film_category ON film_category.film_id=film.film_id
LEFT JOIN ( 
    SELECT customer.customer_id
    FROM  rental 
    JOIN  inventory ON rental.inventory_id=inventory.inventory_id
    JOIN  customer ON rental.customer_id=customer.customer_id
    JOIN  film ON film.film_id=inventory.film_id
    JOIN  film_category ON film_category.film_id=film.film_id
    WHERE film_category.category_id=7
    GROUP BY customer.customer_id
) as DRAMA
ON DRAMA.customer_id=customer.customer_id
WHERE film_category.category_id=5 AND 
DRAMA.customer_id is NULL
GROUP BY customer.customer_id
ORDER by Name;

基本上我们在这里做的是形成两组数据,只是从集合A中获取不与集合B重叠的客户。

答案 1 :(得分:0)

此查询为每个租约返回一行,其中category_id为5而不是7 - 这是一个冗余条件,因为5显然不是7。

解决此类问题的一种简单方法是使用category_id的5s和7s计算每个客户的行数:

SELECT   CONCAT(customer.first_name,' ',customer.last_name) as Name
FROM     rental 
JOIN     inventory ON rental.inventory_id=inventory.inventory_id
JOIN     customer ON rental.customer_id=customer.customer_id
JOIN     film ON film.film_id=inventory.film_id
JOIN     film_category ON film_category.film_id=film.film_id
GROUP BY customer.first_name, customer.last_name
HAVING   COUNT(CASE film_category.category_id WHEN 5 THEN 1 END) > 0 AND
         COUNT(CASE film_category.category_id WHEN 7 THEN 1 END) = 0
ORDER BY 1;

答案 2 :(得分:0)

你应该开始以一种方式思考。让我们有一套A作为一组客户租用'喜剧'并设置B租用'戏剧'的客户。然后你只需要A - B.它可以用MySql编写,例如使用NOT IN

SELECT DISTINCT CONCAT(customer.first_name,' ',customer.last_name) as Name
FROM  customer 
WHERE customer.customer_id IN (
    SELECT rental.customer_id
    FROM rental 
    JOIN inventory ON rental.inventory_id=inventory.inventory_id
    JOIN  film ON film.film_id=inventory.film_id
    JOIN  film_category ON film_category.film_id=film.film_id
    WHERE film_category.category_id=5
) AND 
      customer.customer_id NOT IN (
    SELECT rental.customer_id
    FROM rental 
    JOIN inventory ON rental.inventory_id=inventory.inventory_id
    JOIN  film ON film.film_id=inventory.film_id
    JOIN  film_category ON film_category.film_id=film.film_id
    WHERE film_category.category_id=7
)

请注意,如果NULL中没有rental.customer_id,此查询将有效。