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 0
、select *
或select null
,这并不重要。
感谢您的快速回复。刚刚玩了一下存在,绝对是我会读到的东西。感谢您抽出宝贵时间回复!以上是关于SQL Server - Sakila DB的主要内容,如果未能解决你的问题,请参考以下文章