当前位置:首页 > 文章列表 > 数据库 > MySQL > leetcode SQL题目解析

leetcode SQL题目解析

来源:SegmentFault 2023-01-23 21:09:23 0浏览 收藏

在数据库实战开发的过程中,我们经常会遇到一些这样那样的问题,然后要卡好半天,等问题解决了才发现原来一些细节知识点还是没有掌握好。今天golang学习网就整理分享《leetcode SQL题目解析》,聊聊MySQL、Node.js,希望可以帮助到正在努力赚钱的你。

image

题目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删除
MySQL8.0新特性集锦MySQL8.0新特性集锦
上一篇
MySQL8.0新特性集锦
一次 group by + order by 性能优化分析
下一篇
一次 group by + order by 性能优化分析
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    508次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    497次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • 笔灵AI生成答辩PPT:高效制作学术与职场PPT的利器
    笔灵AI生成答辩PPT
    探索笔灵AI生成答辩PPT的强大功能,快速制作高质量答辩PPT。精准内容提取、多样模板匹配、数据可视化、配套自述稿生成,让您的学术和职场展示更加专业与高效。
    16次使用
  • 知网AIGC检测服务系统:精准识别学术文本中的AI生成内容
    知网AIGC检测服务系统
    知网AIGC检测服务系统,专注于检测学术文本中的疑似AI生成内容。依托知网海量高质量文献资源,结合先进的“知识增强AIGC检测技术”,系统能够从语言模式和语义逻辑两方面精准识别AI生成内容,适用于学术研究、教育和企业领域,确保文本的真实性和原创性。
    25次使用
  • AIGC检测服务:AIbiye助力确保论文原创性
    AIGC检测-Aibiye
    AIbiye官网推出的AIGC检测服务,专注于检测ChatGPT、Gemini、Claude等AIGC工具生成的文本,帮助用户确保论文的原创性和学术规范。支持txt和doc(x)格式,检测范围为论文正文,提供高准确性和便捷的用户体验。
    30次使用
  • 易笔AI论文平台:快速生成高质量学术论文的利器
    易笔AI论文
    易笔AI论文平台提供自动写作、格式校对、查重检测等功能,支持多种学术领域的论文生成。价格优惠,界面友好,操作简便,适用于学术研究者、学生及论文辅导机构。
    42次使用
  • 笔启AI论文写作平台:多类型论文生成与多语言支持
    笔启AI论文写作平台
    笔启AI论文写作平台提供多类型论文生成服务,支持多语言写作,满足学术研究者、学生和职场人士的需求。平台采用AI 4.0版本,确保论文质量和原创性,并提供查重保障和隐私保护。
    35次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码