🎈写在前面
🙋♂️大家好呀,我是超梦。小伙伴们都知道,不管是在学习中还是日常工作中,几乎天天是要跟数据库打交道的,为了更好的操作数据库,我们的SQL知识储备是必不可少的。想要掌握好SQL,那少不了每天的练习与学习。接下来小梦会带领小伙伴们一起每天刷一道LeetCode-数据库(SQL)相关的题目,然后在文章后例举相关知识点帮助小伙伴们学习与巩固,更好的掌握SQL。
🙋♂️ 小伙伴们如果在学习过程中有不明白的地方,欢迎评论区留言提问,小梦定知无不言,言无不尽。
目录
📕SQL题目概述
📕解题思路
📒方法一
📒方法二
📕代码测试
📒方法一
📒方法二
📕知识点小结
📕SQL题目概述
Customers
表:+----+-------+ | Id | Name | +----+-------+ | 1 | Joe | | 2 | Henry | | 3 | Sam | | 4 | Max | +----+-------+
Orders
表:+----+------------+ | Id | CustomerId | +----+------------+ | 1 | 3 | | 2 | 1 | +----+------------+
某网站包含两个表,
Customers
表和Orders
表。编写一个 SQL 查询,找出所有从不订购任何东西的客户。例如给定上述表格,你的查询应返回:
+-----------+ | Customers | +-----------+ | Henry | | Max | +-----------+
LeetCode原题链接~ 点击进入https://leetcode-cn.com/problems/customers-who-never-order/
📕解题思路
根据题目,我们先看题目要求我们查什么,要查出从不订购任何东西的顾客。根据这一点我们可以从
Orders
订单表中得知CustomerId为1和3的是订购过东西的顾客,而2和4则没有订购过任何东西。再从Customers
顾客表中查id2与id4对应的顾客名字就查到了。
📒方法一
1. 根据解题思路,我们可以先写一个子查询查出Orders订单表中对应的CustomerId顾客Id
select customerid from orders;
2. 查出顾客Id后,我们就知道谁买过东西谁从来不买东西。我们再通过NOT IN子句给顾客Id做限制,查Customers表中顾客Id不在Orders表中的就是题目所要求的。
select customers.name as 'Customers' from customers where customers.id not in (select customerid from orders);
LeetCode原题解析https://leetcode-cn.com/problems/customers-who-never-order/solution/cong-bu-ding-gou-de-ke-hu-by-leetcode/
📒方法二
我们通过左外链接,把
Customers
表与Orders
表链接起来,我们只需要查链接后Orders表的数据为NULL的数据,就是从来没有买过东西的顾客。select c.name as Customers from Customers c left join Orders o on c.id = o.CustomerId where o.id is null;
📕代码测试
📒方法一
SQL代码
select customers.name as 'Customers' from customers where customers.id not in (select customerid from orders);
执行代码,测试
测试成功!
📒方法二
SQL代码
select c.name as Customers from Customers c left join Orders o on c.id = o.CustomerId where o.id is null;
执行代码,测试
测试成功
📕知识点小结
外连接分为三种:左外连接(left join),右外连接(right join),全外连接(full join)。这里我们省略了outer 这个关键字。
外连接的一个重要特点:至少有一方保留全集,没有匹配行用NULL代替。
下面小梦把这三种外连接简单说一下:
1. LEFT OUTER JOIN,简称LEFT JOIN,左外连接(左连接)
结果集保留左表的所有行,但右表只包含与左表匹配的行。右表相应的空行为NULL值。
SELECT * FROM 表1 LEFT JOIN 表2 ON 表1.xx = 表2.xx
2. RIGHT OUTER JOIN,简称RIGHT JOIN,右外连接 (右连接)
结果集保留右表的所有行,但左表只包含与右表匹配的行。左表相应的空行为NULL值。
SELECT * FROM 表1 RIGHT JOIN 表2 ON 表1.xx = 表2.xx
3. FULL OUTER JOIN,简称FULL JOIN,全外连接
会把两个表所有的行都显示在结果表中。
SELECT * FROM 表1 FULL JOIN 表2 ON 表1.xx = 表2.xx
内连接与外连接
表1 classa
表2 classb
1. 内连接 inner join (join 默认就是内连接)
表1与表2的交集,用上面两个表演示一下
select classa.id as aid,classb.id as bid from classa inner join classb on classa.id = classb.id;
查询的结果是classa与classb的交集
2. 左外连接 left join
结果集保留左表的所有行,但右表只包含与左表匹配的行。右表相应的空行为NULL值。
select classa.id as aid,classb.id as bid from classa left join classb on classa.id = classb.id;
3. 右外连接 right join
结果集保留右表的所有行,但左表只包含与右表匹配的行。左表相应的空行为NULL值。
select classa.id as aid,classb.id as bid from classa right join classb on classa.id = classb.id;
4. 全外连接 full join
会把两个表所有的行都显示在结果表中。
select classa.id as aid,classb.id as bid from classa full join classb on classa.id = classb.id;
小伙伴们注意啦!!!
MySQL不支持full join!!!MySQL不支持full join!!!MySQL不支持full join!!!
重要的事情要说三遍!!!那怎么实现和full join一样的效果呢?那就要通过使用union来实现,具体实现SQL语句如下
select classa.id as aid,classb.id as bid from classa left join classb on classa.id = classb.id union select classa.id as aid,classb.id as bid from classa right join classb on classa.id = classb.id;
😀感谢小伙伴们支持,如果有什么疑问,欢迎留言询问,小梦定知无不言,言无不尽!