题目描述
某网站包含两个表,Customers
表和 Orders
表。编写一个 SQL 查询,找出所有从不订购任何东西的客户。
Customers
表:
Id | Name |
---|---|
1 | Joe |
2 | Henry |
3 | Sam |
4 | Max |
Orders
表:
Id | CustomerId |
---|---|
1 | 3 |
2 | 1 |
例如给定上述表格,你的查询应返回:
Customer |
---|
Henry |
Max |
相关知识
此题不需要前置知识
解题过程
-
分析题意
- 此题是要找Customers表中涉及到,而Orders表未涉及到的内容,所以是使用左连接
- Customers与Orders进行左连接,连接条件为Customers.Id与Orders.CustomerId,寻找Orders.Id为空
-
编写sql
SELECT `Name` AS Customers FROM Customers left join Orders ON Customers.Id =Orders.CustomerId WHERE Orders.Id IS NULL
-
提交,运行通过
-
查看题解,发现有人用三种方法进行实现
select c.Name as Customers from Customers c left join Orders o on o.CustomerId = c.Id where o.Id is null; select c.Name as Customers from Customers c where not exists (select 1 from Orders o where o.CustomerId = c.Id); select c.Name as Customers from Customers c where c.Id not in (select distinct o.CustomerId from Orders o);
- EXISTS关键字
- EXISTS 指定一个子查询,检查子查询是否至少会返回一行数据
- 语法为 EXISTS subquery,返回值不是行的内容,而是Boolean,如果子查询有行则返回True
- EXISTS在表特别大时效率会高
- IN关键字
- value IN (value1, value2 ,……) 相当于 value=value OR value =value2 OR value =…..
- 如果value在这个集合里,则返回True,否则返回False
- 这个集合也可以是一个subquery
- IN关键字和NOT IN关键字要避免使用
- IN和NOT IN效率低
- IN和NOT IN容易出错
- EXISTS关键字
学习总结
- 此题主要考察外连接,外连接中使用了一个关键字ON,设定连接条件,所以再加上WHERE实际上进行了两次筛选。
- 子查询
- 子查询是将本查询的结果作为主查询的数据来源或判断条件的查询
- 子查询要使用小括号
- 子查询又叫嵌套查询
- 子查询常常有
- SELECT,仅支持标量子查询
- FROM,支持表子查询
- WHERE/HAVING,标量子查询、列子查询、行子查询
- EXISTS 相关子查询
- 按结果的行数分为
- 标量子查询 结果只有一行一列
- 行子查询 结果只有一行多列
- 列子查询 结果只有一列多行
- 表子查询 结果一般为多行多列
- 按父子查询的关系分为
- 无关子查询:子查询在执行时与父查询没有关系,子查询可以单独执行
- 相关子查询:子查询在执行时与需查询有关系,子查询不能单独执行
- 子查询的执行优先于主查询执行,主查询的条件使用到了子查询的结果
- 子查询最多可嵌套32层