Leetcode数据库系列题解合集

写在前面

1、该博文为复习数据库的sql语句的编写。

2、每个题都会有所收获。

5、★ 为自己完全不会的题目,参照了大神的题解

4、 所有代码全部在托管平台上保存,使用可自取。
github地址:https://github.com/MaeStrive/algorithm
gitee地址: 暂时未放

5、为什么那么多题要会员才能做啊 😭😭😭😭😭😭

6、预计 更新完成时间:不详

简单题

175.组合两个表

# Write your MySQL query statement below
select p.firstname,p.lastname,a.city,a.state 
from person as p 
left join address as a 
on p.personId=a.personId

题目中说: 如果 personId 的地址不在 Address 表中,则报告为空 null
所以妥妥左外连接。

  • 左外连接(left join):保存左表的所有记录,与右表连接。如果符合条件就与左表连接,否则用NULL值与左表连接。
  • where/内连接(inner join):仅保存的是两表的符合条件的记录

181.超过经理收入的员工

子查询:

# Write your MySQL query statement below
select e.name as Employee 
from Employee as e
 where e.salary>(
 select m.salary 
 from Employee as m 
 where e.managerId=m.id)

自连接:

# Write your MySQL query statement below
select e.name as Employee 
from Employee as e,Employee as m 
where e.salary>m.salary and m.id=e.managerId

通过这道题又学到一点,因为题目说只返回名字,案例中表头返回的是Employee,所以就让name作为Employee

  • 子查询:把select的结果当作一个值,进一步做查询
  • 自连接:一个表自己和自己连接

182.查询重复邮箱

# Write your MySQL query statement below
select Email 
from Person 
group by Email
having(count(*)>1) 
  • group by:对字段进行分组
  • having与where:where是分组前筛选,having是分组后筛选

执行顺序:where>group by>having>order by

该题目执行顺序:先查询所有邮箱(1),然后对(1)的结果进行筛选,邮箱的个数大于1的邮箱被筛选出来。

183.从不订购的客户

子查询:
查询c表中的id 不包含在 o表中的customerId

# Write your MySQL query statement below
select c.Name as Customers
from Customers as c 
where c.id not in (
select o.CustomerId 
from Orders as o)   

左外连接:
右表中不符合条件的列对应字段会为null值,那么我们就取这些对应null值的列

# Write your MySQL query statement below
select c.Name as Customers 
from Customers as c 
left join Orders as o 
on c.id=o.CustomerId 
where o.id is null

注意:判断null 只能用is,不能够采用操作符(= <>)!

196.删除重复的电子邮箱

两个表关联,删id大的哦

# Please write a DELETE statement and DO NOT write a SELECT statement.
# Write your MySQL query statement below
delete p1 from Person p1,Person p2
where p1.email=p2.email and p1.id>p2.id

197.上升的温度

这道题主要是学会了一个函数datediff ,比较两个日期的大小。

w2的日期比w1的日期大1

datediff(w2.recordDate,w1.recordDate)=1
# Write your MySQL query statement below
select w2.id as Id
from Weather as w1,Weather as w2
where datediff(w2.recordDate,w1.recordDate)=1
and w1.temperature<w2.temperature

还有注意 他题目的表头是Id 不是id ???

584.寻找用户推荐人

这道题小学生都会做,但是我写错了!菜鸡是我 我是菜鸡
注意:
1、NULL值不能做比较
2、NULL值要用is、not is (上面说过)

# Write your MySQL query statement below
select name
from customer as c
where c.referee_id <> 2 or c.referee_id is null

586.订单最多的客户

先按订单分组,由于订单最多的客户唯一,所以降序排,第一个就是最多的

# Write your MySQL query statement below
select customer_number
from Orders as o
group by customer_number
order by count(*) desc
limit 1

595.大的国家

????

# Write your MySQL query statement below
select name,population,area
from World
where area>=3000000
or population>=25000000

596.超过5名学生的课

# Write your MySQL query statement below
select class
from Courses
group by class
having(count(*)>=5)

607.销售员

先将后两个表依据公司id连接,并且筛选出公司名等于’RED‘的 销售人id,
然后第一个表的销售员id不在其中,就可以了。

# Write your MySQL query statement below
select name
from SalesPerson
where sales_id not in(
    select o.sales_id 
    from Orders as o
    left join Company as c
    on o.com_id=c.com_id
    where c.name = "RED"
)

620.有趣的电影

这道题 学习了一手 模运算函数
mod(a,b) 即 a%b

# Write your MySQL query statement below
select id,movie,description,rating
from cinema
where description <> "boring"
and id%2<>0
order by rating desc

627.变更性别

没啥说的啊

# Write your MySQL query statement below
update  Salary 
set sex=if(sex='f','m','f')

1484.按日期分组销售产品

学函数:

group_concat([DISTINCT] 要连接的字段
 [Order BY ASC/DESC 排序字段] [Separator '分隔符'])

分隔符默认为 ,

# Write your MySQL query statement below
select sell_date,(
    count(distinct product)
) as num_sold,(
    group_concat(distinct product order by product Separator ',')
) as products
from Activities
group by sell_date
order by sell_date asc

1527.患某种疾病的患者 ★

正确做法:

正则表达式

# Write your MySQL query statement below
select patient_id,patient_name,conditions
from Patients
where conditions rlike '^DIAB1|.*\\sDIAB1';

抄的题解 表示自己 看不懂 正则表达式

自己的做法
面向结果编程:

最后一个加个空格 ,这样就能防止 ADIAB1 这种情况了

# Write your MySQL query statement below
select patient_id,patient_name,conditions
from Patients
where conditions like 'DIAB1%' or conditions like '% DIAB1%' 

1667.修复表中的名字

学几个函数:

  • concat(a,b):拼接a,b字符串
  • left(a,len):从字符串a的左边截取长度为len的字符串
  • right(a,len):从字符串a的右边开始截取长度为len的字符串
  • upper():字符串变大写
  • lower():字符串变小写
  • substring(a,start,[len]):在a字符串中从start开始截取len长度的字符串(len 省略则表示截取到字符串末尾)
# Write your MySQL query statement below
select user_id,(
    concat(upper(left(name,1)),lower(substring(name,2)))
) as name
from Users
order by user_id asc

1757.可回收且低脂的产品

# Write your MySQL query statement below
select product_id
from Products
where low_fats='Y'
and recyclable='Y'

1873.计算特殊奖金

like进行模糊查询
%、_:通配符
%:表示任意数量字符
_:表示一位字符

# Write your MySQL query statement below
select employee_id,(
    if(mod(employee_id,2)=1 and name not like 'M%',salary,0)
    )as bonus
from Employees
order by employee_id asc

中等题

176.第二高的薪水

这道题分页查询(太熟悉了!!!)。
还没这么简单 需要判断是否为null,好吧……
还要注意去重,最后一个样例是相同的薪水,应该返回null,不然就错了!

# Write your MySQL query statement below
select
ifnull((
    select distinct salary
    from Employee
    order by salary desc 
    limit 1,1
    ),null)
as SecondHighestSalary
  • limit
    两个参数:第一个参数为结果的索引值,从第几行开始(从0开始,不写默认为0),第二个参数表示要查询几条数据
  • ifnull(A,B)
    如果不为null,结果为A,否则结果为B

177.第N高的薪水

这道题跟176差不多一样,但是这道题我学到了 一点东西。
limit方法不能参与运算,所以在外面将n设置为n-1 (索引从0开始)

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
  set n=n-1;
  RETURN (
      # Write your MySQL query statement below.
      select 
      ifnull((
       select distinct salary
       from Employee
        order by salary desc
        limit n,1
      ),null)
      as  getNthHighestSalary
  );
END

178.分数排名 ★

这题不太会写啊,自己只会写个分数排序 😡😡😡😡😡😡

看了大神的题解之后,自己理一理。
这题难得就是如何把相同分数设置成同一个rank。
原来有函数

引用了 乔治二大爷的题解

  • 1.rank() over:排名相同的两名是并列,但是占两个名次,1 1 3 4 4 6这种

  • 2.dense_rank() over:排名相同的两名是并列,共占一个名词,1 1 2 3 3 4这种

  • 3.row_number() over:这个函数不需要考虑是否并列,哪怕根据条件查询出来的数值相同也会进行连续排名 1 2 3 4 5

那就简单多了啊 感谢大佬

# Write your MySQL query statement below
select score,
    dense_rank() over (order by score desc) as `rank`
from Scores
order by score desc

180.连续出现的数字 ★

还是一点不会,怎么判断连续啊!!
看了官方题解 ,原来还能这么解!!!! 😦😦😦

简单说,就是判断三个id是否递增,并且数字是否相同,对了 注意去重!

# Write your MySQL query statement below
select distinct l1.num as ConsecutiveNums
from Logs l1,Logs l2,Logs l3
where l1.id=l2.id-1
    and l2.id=l3.id-1
    and l2.num=l1.num
    and l3.num=l2.num

184.部门工资最高的员工 ★

又不会,我是菜鸡 😡
官方题解:
先查找每个部门中的最高工资(1),然后每个关联两个表,再查找部门id和工资 在(1)表中的员工。
这也太强了吧。。
这道题 还学会了
in 可以同时判断多个字段

# Write your MySQL query statement below
select d.name as Department,e.name as Employee,e.salary as Salary
from Employee as e
left join Department as d
on e.departmentId=d.id
where ((e.departmentId,e.salary)
    in (select departmentId,max(salary)
        from Employee
        group by departmentId
        )
)

626.换座位

这道题有了180那道题的解题思路就差不多能想到(不管想法多么单纯,试试就行,毕竟不是算法题)
这道题还学到了 条件控制语句

case
	when …… then
	when …… then
	else
end

即:将 id进行变换,如果id等于奇数(不是最后一个)就查id+1,偶数查id-1 将这些字段都当作id

# Write your MySQL query statement below
select  
(case 
    when mod(id,2)=1 and (id<>(select count(*) from Seat)) then id+1
    when mod(id,2)=0 then id-1
    else id
end) as id,student
from Seat
order by id asc

608.树节点

使用 条件判断 :
父节点为空 那么就是根节点。
然后 判断 该节点是否是其他节点的父节点,如果是 就是Inner 否则 Leaf

# Write your MySQL query statement below
select id,
(case 
    when p_id is null then 'Root'
    when id in (select t1.id from tree t1,tree t2 where t2.p_id=t1.id) then 'Inner'
    else 'Leaf'
end)as 'type'
from tree

1393.股票的资本损益

这道题很巧妙 买就是负,卖就是正!

# Write your MySQL query statement below
select s.stock_name,
    sum(if(s.operation='Buy',-price,price)) as capital_gain_loss
from Stocks s
group by s.stock_name

困难题

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐