原题:https://leetcode-cn.com/problems/customers-who-never-order/
我自己做leetcode的数据库题目的解题记录:
解题目录 https://blog.csdn.net/weixin_42845682/article/details/105196004
题目描述:
某网站包含两个表,Customers 表和 Orders 表。编写一个 SQL 查询,找出所有从不订购任何东西的客户。
+----+-------+
| Id | Name |
+----+-------+
| 1 | Joe |
| 2 | Henry |
| 3 | Sam |
| 4 | Max |
+----+-------+
Orders 表:
+----+------------+
| Id | CustomerId |
+----+------------+
| 1 | 3 |
| 2 | 1 |
+----+------------+
例如给定上述表格,你的查询应返回:
+-----------+
| Customers |
+-----------+
| Henry |
| Max |
+-----------+
答案:
第一种答案
感觉这道题很简单,没啥做的。。。
select
name customers
from Customers
where id not in
(
select
distinct(c.id)
from Customers c
join orders o on c.id=o.Customerid
)
第二种答案
看了一看表结构,感觉其实不用那么麻烦…
select
name customers
from Customers
where id not in
(
select
distinct(CustomerId)
from Orders
)
第三种答案
前面两种做法都是求并集,然后不存在。也可以求差集然后存在(不过mysql里我记得没有差集,所以用oracle做了):
SELECT
name customers
from
customers c
where id in
(
SELECT id FROM Customers
minus
SELECT distinct(customerid) FROM Orders
)
但是这种写法,好像执行起来很慢,leetcode显示用了1914 ms。不知道是leetcode出问题了还是我的写法不对。
第四种答案
其实吧,用join也能做这道题。如果看不懂,推荐这篇:
用join实现交集,并集,差集,补集的效果
https://blog.csdn.net/weixin_42845682/article/details/105414734
select
distinct(c.name) customers
from customers c
left join orders o on c.id = o.customerid
where o.id is null
但是吧,我想不通,为什么我加distinct还报错了呢。。。不过不是大错,这种都是根据业务需求来的,也许人家重名了呢。
所以正确的答案是:
select
c.name customers
from customers c
left join orders o on c.id = o.customerid
where o.id is null