力扣刷MySQL-第二弹(详细解析)

本文涉及的产品
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: 力扣刷MySQL-第二弹(详细解析)

🚀查找重复的电子邮箱

表: Person

+-------------+---------+

| Column Name | Type    |

+-------------+---------+

| id          | int     |

| email       | varchar |

+-------------+---------+

id 是该表的主键(具有唯一值的列)。

此表的每一行都包含一封电子邮件。电子邮件不包含大写字母。

编写解决方案来报告所有重复的电子邮件。 请注意,可以保证电子邮件字段不为 NULL。

以 任意顺序 返回结果表。

结果格式如下例。

示例 1:

输入:

Person 表:

+----+---------+

| id | email   |

+----+---------+

| 1  | a@b.com |

| 2  | c@d.com |

| 3  | a@b.com |

+----+---------+

输出:

+---------+

| Email   |

+---------+

| a@b.com |

+---------+

解释: a@b.com 出现了两次。

解法一:

1.自连接

2.因为实际上就这一个表,一般这类题目都是首选用自连接的方法

3.那么自连接就是需要起别名

4.这里我们肯定是把它想成两个表,一个p1,一个p

5.那么我们自连接后面的on的条件是什么?

6.因为要找重复的邮箱,所以我们肯定是找两个表相同的邮箱,即p1.email = p2.email

7.但是只有这一个条件肯定是不够的,因为你这里是把它想成了两张表,但实际上这两张表本来就是一样的,它们两的字段email里面的value本身也就是一样的,你只有这一个条件,没有任何意义

8.所以还需要一个条件,就是我们是根据不同的id相同的email,这才叫重复

9.连接两个不同的条件用and

10.两个表中id要不相同的去比较,即p1.Id != p2.Id

11.所以写为select p1.Email from Person p1  join Person  p2 on p1.Email = p2.Email AND p1.Id!=p2.Id

12.但此时还是不对的,因为id为1的email=id为3的email,然后id为3的email=id为1的email,相当于最后输出email,会输出两次一样的,重复了

13.那么最后一步就是去重,用关键字distinct,代码如下

select distinct(p1.Email) from Person p1  
join Person  p2 on p1.Email = p2.Email AND p1.Id!=p2.Id

执行:


解法二:

1.使用 GROUP BY 和 HAVING 子句

2.这个解法首先按照电子邮件地址分组,然后使用 HAVING 子句筛选出出现次数大于 1 的电子邮件地址,从而找出重复的电子邮件。

SELECT email
FROM Person
GROUP BY email
HAVING COUNT(email) > 1;

解法三:

1.使用子查询

2.这个解法使用了子查询,首先在子查询中找出重复的电子邮件,然后在外部查询中选择出现在子查询结果中的电子邮件。

3.这个意思就相当于把解法2作为一个嵌套select,只是没有去重,然后外部再套一个select用于去找子查询中的email

5.用where去筛查子查询中的电子邮件

6.代码如下:

SELECT email
FROM Person
WHERE email IN (
    SELECT email
    FROM Person
    GROUP BY email
    HAVING COUNT(email) > 1
);

不过博主比较推荐用第一种和第二种,逻辑比较清晰,最后一种相当于画蛇添足

🚀查找没有买东西的顾客

Customers 表:

+-------------+---------+

| Column Name | Type    |

+-------------+---------+

| id          | int     |

| name        | varchar |

+-------------+---------+

在 SQL 中,id 是该表的主键。

该表的每一行都表示客户的 ID 和名称。

Orders 表:

+-------------+------+

| Column Name | Type |

+-------------+------+

| id          | int  |

| customerId  | int  |

+-------------+------+

在 SQL 中,id 是该表的主键。

customerId 是 Customers 表中 ID 的外键( Pandas 中的连接键)。

该表的每一行都表示订单的 ID 和订购该订单的客户的 ID。

找出所有从不点任何东西的顾客。

以 任意顺序 返回结果表。

结果格式如下所示。

示例 1:

输入:

Customers 表:

+----+-------+

| id | name  |

+----+-------+

| 1  | Joe   |

| 2  | Henry |

| 3  | Sam   |

| 4  | Max   |

+----+-------+

Orders 表:

+----+------------+

| id | customerId |

+----+------------+

| 1  | 3          |

| 2  | 1          |

+----+------------+

输出:

+-----------+

| Customers |

+-----------+

| Henry     |

| Max       |

+-----------+

解法一:

1.要找出所有从不点任何东西的顾客,我们可以使用 SQL 中的 LEFT JOIN 和 IS NULL 来解决这个问题。

2.左外连接相当于查询左表的所有数据,也包含了左表和右表交集部分的数据

3.所以我们肯定是select * from  Customers left join  Orders on 条件

4.我们肯定是要给表取一个别名比较方便简

5.SELECT * FROM Customers c LEFT JOIN Orders o ON 条件

6.那么现在最重要的其实就是我们的ON后面的连接条件到底是什么?

7.即用Orders的外键,去关联Customers的主键,因为实际上Orders的外键代表的就是Customers的主键,所有条件是O.customerId = C.Id

8.即SELECT * FROM Customers c LEFT JOIN Orders o ON c.id = o.customerId

9.此时只是左外连接成功了,但是我们还没有完成,它只是把所有数据返回了,这时候我们要进行筛选

10.筛选我们用到where条件,那么where后面的条件如何写呢?

8..我们会把左表的所有数据返回,包括没有买东西的顾客和他们的订单,那么没有买东西的顾客就是null

9.我们再用where子句去过滤出Orders 表中没有对应订单的顾客,即 o.id IS NULL。这样就能找出所有从不点任何东西的顾客。

10.SELECT * FROM Customers c LEFT JOIN Orders o ON c.id = o.customerId WHERE o.id IS NULL;

11.再把*优化一下,代码如下:

SELECT c.name AS Customers
FROM Customers c
LEFT JOIN Orders o ON c.id = o.customerId
WHERE o.id IS NULL;

🚀总结

这个查询首先从 Customers 表中选择顾客的名称,并左连接 Orders 表,以便找出所有顾客和他们的订单。然后使用 WHERE 子句过滤出在 Orders 表中没有对应订单的顾客,即 o.id IS NULL。这样就能找出所有从不点任何东西的顾客。

在这个示例中,查询的结果会返回 Henry 和 Max,因为他们在 Orders 表中没有对应的订单记录。

解法二:

1.运用not in去找Customers表中谁的id,没有在Orders表中的CustomerId中

2.意思也就是,这4个人,谁没有顾客订单,我们就返回谁的名字

3.select * from Customers c where c.id not in  (select CustomerId from Orders)

4.优化一下*,返回名字,然后字段取需要的别名Customers

5.代码如下

select Name Customers
from Customers c
where c.Id not in (
    select CustomerId from Orders
)
相关文章
|
11月前
|
算法 Go 索引
【LeetCode 热题100】45:跳跃游戏 II(详细解析)(Go语言版)
本文详细解析了力扣第45题“跳跃游戏II”的三种解法:贪心算法、动态规划和反向贪心。贪心算法通过选择每一步能跳到的最远位置,实现O(n)时间复杂度与O(1)空间复杂度,是面试首选;动态规划以自底向上的方式构建状态转移方程,适合初学者理解但效率较低;反向贪心从终点逆向寻找最优跳点,逻辑清晰但性能欠佳。文章对比了各方法的优劣,并提供了Go语言代码实现,助你掌握最小跳跃次数问题的核心技巧。
460 15
|
5月前
|
存储 人工智能 算法
从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
在算法世界里,有一种思想如同生活中的"见好就收"——每次做出当前看来最优的选择,寄希望于通过局部最优达成全局最优。这种思想就是贪心算法,它以其简洁高效的特点,成为解决最优问题的利器。今天我们就来系统学习贪心算法的核心思想,并通过10道LeetCode经典题目实战演练,带你掌握这种"步步为营"的解题思维。
|
7月前
|
存储 SQL 关系型数据库
MySQL中binlog、redolog与undolog的不同之处解析
每个都扮演回答回溯与错误修正机构角色: BinLog像历史记载员详细记载每件大大小小事件; RedoLog则像紧急救援队伍遇见突發情況追踪最后活动轨迹尽力补救; UndoLog就类似时间机器可倒带历史让一切归位原始样貌同时兼具平行宇宙观察能让多人同时看见各自期望看见历程而互不干扰.
412 9
|
8月前
|
存储 SQL 关系型数据库
MySQL 核心知识与索引优化全解析
本文系统梳理了 MySQL 的核心知识与索引优化策略。在基础概念部分,阐述了 char 与 varchar 在存储方式和性能上的差异,以及事务的 ACID 特性、并发事务问题及对应的隔离级别(MySQL 默认 REPEATABLE READ)。 索引基础部分,详解了 InnoDB 默认的 B+tree 索引结构(多路平衡树、叶子节点存数据、双向链表支持区间查询),区分了聚簇索引(数据与索引共存,唯一)和二级索引(数据与索引分离,多个),解释了回表查询的概念及优化方法,并分析了 B+tree 作为索引结构的优势(树高低、效率稳、支持区间查询)。 索引优化部分,列出了索引创建的六大原则
198 2
|
8月前
|
存储 SQL 关系型数据库
MySQL 核心知识与性能优化全解析
我整理的这份内容涵盖了 MySQL 诸多核心知识。包括查询语句的书写与执行顺序,多表查询的连接方式及内、外连接的区别。还讲了 CHAR 和 VARCHAR 的差异,索引的类型、底层结构、聚簇与非聚簇之分,以及回表查询、覆盖索引、左前缀原则和索引失效情形,还有建索引的取舍。对比了 MyISAM 和 InnoDB 存储引擎的不同,提及性能优化的多方面方法,以及超大分页处理、慢查询定位与分析等,最后提到了锁和分库分表可参考相关资料。
186 0
|
10月前
|
存储 算法 Go
【LeetCode 热题100】17:电话号码的字母组合(详细解析)(Go语言版)
LeetCode 17题解题思路采用回溯算法,通过递归构建所有可能的组合。关键点包括:每位数字对应多个字母,依次尝试;递归构建下一个字符;递归出口为组合长度等于输入数字长度。Go语言实现中,使用map存储数字到字母的映射,通过回溯函数递归生成组合。时间复杂度为O(3^n * 4^m),空间复杂度为O(n)。类似题目包括括号生成、组合、全排列等。掌握回溯法的核心思想,能够解决多种排列组合问题。
424 11
|
10月前
|
Go
【LeetCode 热题100】155:最小栈(详细解析)(Go语言版)
本文详细解析了力扣热题155:最小栈的解题思路与实现方法。题目要求设计一个支持 push、核心思路是使用辅助栈法,通过两个栈(主栈和辅助栈)来维护当前栈中的最小值。具体操作包括:push 时同步更新辅助栈,pop 时检查是否需要弹出辅助栈的栈顶,getMin 时直接返回辅助栈的栈顶。文章还提供了 Go 语言的实现代码,并对复杂度进行了分析。此外,还介绍了单栈 + 差值记录法的进阶思路,并总结了常见易错点,如 pop 操作时忘记同步弹出辅助栈等。
349 6
|
10月前
|
Go 索引
【LeetCode 热题100】739:每日温度(详细解析)(Go语言版)
这篇文章详细解析了 LeetCode 第 739 题“每日温度”,探讨了如何通过单调栈高效解决问题。题目要求根据每日温度数组,计算出等待更高温度的天数。文中推荐使用单调递减栈,时间复杂度为 O(n),优于暴力解法的 O(n²)。通过实例模拟和代码实现(如 Go 语言版本),清晰展示了栈的操作逻辑。此外,还提供了思维拓展及相关题目推荐,帮助深入理解单调栈的应用场景。
399 6
|
9月前
|
关系型数据库 MySQL
MySQL字符串拼接方法全解析
本文介绍了四种常用的字符串处理函数及其用法。方法一:CONCAT,用于基础拼接,参数含NULL时返回NULL;方法二:CONCAT_WS,带分隔符拼接,自动忽略NULL值;方法三:GROUP_CONCAT,适用于分组拼接,支持去重、排序和自定义分隔符;方法四:算术运算符拼接,仅适用于数值类型,字符串会尝试转为数值处理。通过示例展示了各函数的特点与应用场景。
|
11月前
|
存储 算法 数据可视化
【二叉树遍历入门:从中序遍历到层序与右视图】【LeetCode 热题100】94:二叉树的中序遍历、102:二叉树的层序遍历、199:二叉树的右视图(详细解析)(Go语言版)
本文详细解析了二叉树的三种经典遍历方式:中序遍历(94题)、层序遍历(102题)和右视图(199题)。通过递归与迭代实现中序遍历,深入理解深度优先搜索(DFS);借助队列完成层序遍历和右视图,掌握广度优先搜索(BFS)。文章对比DFS与BFS的思维方式,总结不同遍历的应用场景,为后续构造树结构奠定基础。
531 10

推荐镜像

更多