leetcode SQL题目解析
来源:SegmentFault
时间:2023-01-23 21:09:23 146浏览 收藏
在数据库实战开发的过程中,我们经常会遇到一些这样那样的问题,然后要卡好半天,等问题解决了才发现原来一些细节知识点还是没有掌握好。今天golang学习网就整理分享《leetcode SQL题目解析》,聊聊MySQL、Node.js,希望可以帮助到正在努力赚钱的你。
题目1: 组合两张表
组合两张表, 题目很简单, 主要考察JOIN语法的使用。唯一需要注意的一点, 是题目中的这句话, "无论 person 是否有地址信息"。说明即使Person表, 没有信息我们也需要将Person表的内容进行返回。所以我选择使用左外查询, 当然你也可以选择RIGHT OUTER JOIN, 这取决于你查询语句的写法。
解答
SELECT Person.FirstName, Person.LastName, Address.City, Address.State FROM Person LEFT OUTER JOIN Address ON Person.PersonId = Address.PersonId
题目2: 第二高的薪水
第二高的薪水, 题目本身并不难, 但是请注意, 题目中的描述"如果不存在第二高的薪水,那么查询应返回 null", 这意味着, 如果SQL没有查询到结果, SQL本身需要一个默认的返回值。如何才能做到, 即使没有结果也返回一个值。通过谷歌, 我查找到了解决方案[Returning a value even if no result
](https://stackoverflow.com/que...。使用IFNULL函数, 并且将整个SQL语句作为IFNULL函数的参数。如果IFNULL函数第一个的参数为NULL, 则返回IFNULL函数的第二个参数, 否则返回第一个参数。
解答
SELECT IFNULL( ( SELECT Employee.Salary FROM Employee GROUP BY Employee.Salary ORDER BY Employee.Salary DESC LIMIT 1 OFFSET 1 ), NULL ) AS SecondHighestSalary;
题目3: 分数排名
本题主要考察了, 如何在SQL查询中生成序号, 因为在表中本身是不含有RANK字段的。我通过谷歌, 在stackoverflow上找到了答案, Generate serial number in mysql query。
为查询结果添加序号
解答
# 3. 通过INNER JOIN为没有去重的分数表添加名次的字段 SELECT Scores.Score, RANKINDEX.rank AS RANK FROM Scores INNER JOIN ( # 2. 为排序去重后分数表, 添加名次字段(序号) SELECT RANK.Score AS Score, @a:=@a+1 rank FROM ( # 1. 首先排序并去重分数表 SELECT DISTINCT Scores.Score FROM Scores ORDER BY Scores.Score DESC ) RANK, (SELECT @a:=0) AS a ) AS RANKINDEX ON RANKINDEX.Score = Scores.Score ORDER BY Scores.Score DESC
题目4: 超过经理收入的员工
非常简单的一道题目, 这里不在多做解释
解答
SELECT emp1.Name AS Employee FROM Employee AS emp1, Employee AS emp2 WHERE emp1.ManagerId = emp2.Id AND emp1.Salary > emp2.Salary
题目5: 查找重复的电子邮箱
同样是非常简单的一道题目, 唯一可能需要了解的就是, GROUP BY Person.Email的字句, 可以对Person.Email字段起到去重的作用
解答
SELECT Person.Email AS Email FROM Person GROUP BY Person.Email HAVING COUNT(Person.Email) > 1
题目6: 从不订购的客户
依然是非常简单的一道题目, 主要考察对子查询的使用
解答
SELECT Customers.Name AS Customers FROM Customers WHERE Customers.Id NOT IN ( SELECT Orders.CustomerId FROM Orders )
题目7: 部门工资最高的员工
部门工资最高的员工, 在对这一题目进行解答之前。我们需要明确知道一点。"除聚合, 计算语句外,SELECT语句中的每个列都必须在GROUP BY子句中给出"。也就是说, 我们并不能在求, 每一个部门工资的Max最大值的时候, 把员工的id也计算出来。对于这道题目,我们解答的步骤分为两步, 1. 求出每一个部门对应的最高工资, 并且将结果存储为派生表 2. 根据员工的部门id, 以及员工的工资, 与派生表联结, 比较对应员工的工资是否等于派生表的部门的最高工资。如果等于, 此人的工资就是部门的最高工资
解答
SELECT Department.Name AS Department, Employee.Name AS Employee, Employee.Salary AS Salary FROM Employee INNER JOIN Department INNER JOIN ( # 第一步求出每一个部门的最高工资, 并作为派生表使用 SELECT Max(Employee.Salary) AS Salary, Department.Id AS DepartmentId FROM Employee INNER JOIN Department ON Employee.DepartmentId = Department.Id GROUP BY Employee.DepartmentId ) AS DepartmentBigSalary # 三张表进行联结 ON Employee.DepartmentId = Department.Id AND Department.Id = DepartmentBigSalary.DepartmentId # 比较对应员工的工资是否等于派生表的部门的最高工资 WHERE Employee.Salary = DepartmentBigSalary.Salary
题目8: 删除重复的电子邮箱
DELETE语句在不指定WHERE子句的时候, 默认是删除表中全部的行。题目指定了两个条件, "删除 Person 表中所有重复的电子邮箱,重复的邮箱里只保留 Id 最小 的那个", WHERE同时也需要指定两个条件。两个条件, 请参考下面的代码。唯一值的注意的一点是, DELETE本身是更新操作, 所以在FROM需要新建一个派生表, 否则会产生错误(You can't specify target table 'Person' for update in FROM clause)
解答
DELETE FROM Person WHERE Person.Email IN ( # 条件1: 删除长度大于2的行 SELECT table1.Email FROM ( SELECT Person.Email AS Email FROM Person GROUP BY Person.Email HAVING COUNT(Person.Email) > 1 ) AS table1 ) AND Person.Id NOT IN ( # 条件1: 删除长度大于2的行, 但是不包含id最小的行 SELECT table2.id FROM ( SELECT MIN(Person.Id) AS id FROM Person GROUP BY Person.Email HAVING COUNT(Person.Email) > 1 ) AS table2 )
题目9: 上升的温度
本题主要考察了对自联结的使用。如何判断两个相邻的RecordDate的Temperature的大小?通过对同一张表进行JOIN联结, JOIN的ON的条件修改为w1.RecordDate = DATE_SUB(w2.RecordDate,INTERVAL -1 DAY), w1表的RecordDate是w2表RecordDate前一天, w1的每一行关联的w2的每一行其实w1的后一天。
解答
SELECT w1.Id AS Id FROM Weather AS w1 INNER JOIN Weather AS w2 ON w1.RecordDate = DATE_SUB(w2.RecordDate,INTERVAL -1 DAY) WHERE w1.Temperature > w2.Temperature
题目10: 大的国家
非常简单的一道题, 这里不在赘述
解答
SELECT World.Name AS Name, World.population AS population, World.area AS area FROM World WHERE World.population > 25000000 OR World.area > 3000000
题目11: 超过5名学生的课
超过5名学生的课, 本道题目注意考察点在于对GROUP BY去重效果的认知上。首先子查询的采用嵌套分组。首先使用课程分组然后根据学生进行分组。可以有效去除课程, 学生重复的行。为什么不直接使用学生分组呢?因为这样做会丢失学生的课程信息。在外层的查询中只需要查找中COUNT大于5的课程即可。
解答
SELECT ClassLength.class FROM ( # 排除了学生和课程重复的行 SELECT courses.class AS class FROM courses GROUP BY courses.class, courses.student ) AS ClassLength GROUP BY ClassLength.class HAVING COUNT(ClassLength.class) >= 5
题目12: 有趣的电影
本道题目也较为简单, 考察点在于对于奇偶数的判断上, 我们可以使用MySQL的MOD函数。MOD(N, M), MOD函数将返回N/M的余数
解答
SELECT cinema.id AS id, cinema.movie AS movie, cinema.description AS description, cinema.rating AS rating FROM cinema WHERE cinema.description 'boring' AND MOD(cinema.id, 2) = 1 ORDER BY rating DESC
题目13: 交换工资
题目本身要求使用一个更新查询,并且没有中间临时表。所以SQL中避免不了需要使用逻辑判断, 这里使用MySQl的CASE WHEN语句
解答
UPDATE salary SET salary.sex = ( CASE WHEN salary.sex = 'm' THEN 'f' WHEN salary.sex = 'f' THEN 'm' ELSE 'sex' END )
题目14: 连续出现的数字
与"上升的温度"的题目类似, 合理的使用自联结, 就可以解答出本题
解答
SELECT Consecutive.ConsecutiveNums FROM ( SELECT l1.Num AS ConsecutiveNums FROM Logs AS l1 INNER JOIN Logs AS l2 INNER JOIN Logs AS l3 ON l1.id = l2.id - 1 AND l2.id = l3.id - 1 AND l1.id = l3.id - 2 WHERE l1.Num = l2.Num AND l2.Num = l3.Num AND l1.Num = l3.Num ) AS Consecutive GROUP BY Consecutive.ConsecutiveNums
以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于数据库的相关知识,也可关注golang学习网公众号。
声明:本文转载于:SegmentFault 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
-
499 收藏
-
244 收藏
-
235 收藏
-
157 收藏
-
101 收藏
最新阅读
更多>
-
259 收藏
-
411 收藏
-
476 收藏
-
312 收藏
-
244 收藏
-
195 收藏
课程推荐
更多>
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 507次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习