SQL Server - Sakila DB

Posted

技术标签:

【中文标题】SQL Server - Sakila DB【英文标题】: 【发布时间】:2020-04-25 18:20:03 【问题描述】:

我目前正在使用 MS 的 Sakila DB,其中包含有关电影/演员/租赁/客户等的数据。

地图:

我被要求制定一个查询来查找没有租借特定电影的客户。

我已经能够计算出找到租用该影片的客户的代码,但我无法找到没有租用该影片的客户的名单。

我的代码如下:

SELECT DISTINCT C.customer_id, C.first_name, C.last_name
FROM customer AS C
JOIN RENTAL AS R ON C.customer_id = R.customer_id
JOIN inventory AS I ON R.inventory_id = I.inventory_id
JOIN film AS F ON I.film_id = F.film_id
WHERE F.title = 'ANGELS LIFE'

我可以使用!= 'ANGELS LIFE',但它会返回给我所有租借过任何其他电影的人的名单(包括那些从其他购买中租借过 ANGELS LIFE 的人)。

我无法完成下一步。我考虑过使用Union,然后删除重复项(其中 count(*) >1)也许?

感谢任何建议。

【问题讨论】:

【参考方案1】:

你可以使用聚合:

SELECT C.customer_id, C.first_name, C.last_name
FROM customer AS C JOIN 
     RENTAL AS R 
     ON C.customer_id = R.customer_id JOIN 
     inventory AS I 
     ON R.inventory_id = I.inventory_id JOIN 
     film AS F 
     ON I.film_id = F.film_id
GROUP BY C.customer_id, C.first_name, C.last_name
HAVING SUM(CASE WHEN F.title = 'ANGELS LIFE' THEN 1 ELSE 0 END) = 0;

【讨论】:

谢谢!曾考虑过 HAVING 但认为我遇到了与 WHERE 相同的问题。重新定义结果然后过滤它的绝佳解决方案。再次感谢您!【参考方案2】:

我会推荐带有相关子查询的not exists。在我看来,这就像您所要求的简单而直接的措辞:

select c.*
from customer c
where not exists (
    select 1
    from rental r
    inner join inventory i on i.inventory_id = r.inventory_id
    inner join film f on f.film_id = i.film_id
    where f.title = 'ANGELS LIFE' and r.customer_id = c.customer_id
)

【讨论】:

谢谢!两种方法都试过了,学到了新东西。你介意简单解释一下 select 1 在这里做什么而不是 select * ? @HarryH247: exists 只检查子查询是否返回 something,不管有多少行或它们的内容。所以我们只使用select 1 - 这是一个约定,它很可能是select 0select *select null,这并不重要。 感谢您的快速回复。刚刚玩了一下存在,绝对是我会读到的东西。感谢您抽出宝贵时间回复!

以上是关于SQL Server - Sakila DB的主要内容,如果未能解决你的问题,请参考以下文章

sql Sakila数据库上的SQL子查询。

SAKILA 数据库 SQL 上的多个 JOINS

如何安装MySQL官方的sakila数据库?

Sakila db SQL 查找租借>10部恐怖片的客户

mysqldump常用导出方式

sql分组后取每组前三