【持续更新】Leetcode SQL题目全解析(附建表sql)

本文提供了一系列LeetCode SQL题目的详细解答,涵盖了从基础操作到复杂查询的各种场景,如表连接、聚合函数、子查询等。通过实例解析,帮助读者掌握SQL在解决实际问题中的应用,并提供了MySQL环境下的建表语句。
摘要由CSDN通过智能技术生成

越前须知(雾)

  • 本系列将详解Leetcode的SQL题库(附建表语句),采用DBMS为MySQL。
  • 本系列仅提供博主个人解法,均经过MySQL检验,且解法有对应注意点,请放心食用。
  • 本系列适合从入门到进阶选手;若希望系统学习SQL进阶知识,请移步博主主页。

题目Q & A

175 组合两个表

  • 创表
create table Person 
(personid int,
 firstname varchar(255), 
 lastname varchar(255));
 
create table Address 
(addressid int,
 personid int, 
 city varchar(255), 
 state varchar(255));
 
insert into Person values (1, 'San', 'Zhang');
insert into Person values (2, 'Si',  'Li') ;

insert into Address values ('291', 1, 'New York City', 'New York');

Q:查询Person表中成员的名、姓、城市、州
A:以Person表为主,外连接

select firstname, lastname, city, state
	from Person left outer join Address
    on Person.personid = Address.personid;

181 超过经理收入的员工

  • 创表
Create table If Not Exists Employee 
(Id int, 
 Name varchar(255), 
 Salary int, 
 ManagerId int);
 
Truncate table Employee;
insert into Employee (Id, Name, Salary, ManagerId) values ('1', 'Joe', '70000', '3');
insert into Employee (Id, Name, Salary, ManagerId) values ('2', 'Henry', '80000', '4');
insert into Employee (Id, Name, Salary, ManagerId) values ('3', 'Sam', '60000', null);
insert into Employee (Id, Name, Salary, ManagerId) values ('4', 'Max', '90000', null);

Q:查询工资超过其对应经理的员工名字
A:不是每个员工都有对应经理,内连接,匹配字段分别为经理id和员工id

select E1.name
	from Employee E1, Employee E2
	where E1.managerid = E2.id  -- 经理也是员工
    and E1.salary > E2.salary;

182 查找重复电子邮箱

  • 创表
create table Email
(id char(4),
 email varchar(50));
 
truncate table Email;
insert into Email values ('1', 'a@b.com');
insert into Email values ('2', 'c@d.com');
insert into Email values ('3', 'a@b.com');

Q:查询重复的电子邮箱
A:COUNT(*)>1 / 自连接

  • COUNT(*)
select email
	from Email
    group by email
    having count(*) > 1;
  • 自连接,相当于查询邮箱相同但ID不同的“错填”信息
select distinct E1.email
	from Email E1, Email E2
    where E1.email = E2.email
    and E1.id <> E2.id;

183 从不订购的用户

  • 创表
create table Customers
(id char(4),
 name varchar(10));
 
create table Orders
(id char(4),
 customerid char(4));

insert into Customers values ('1', 'Joe');
insert into Customers values ('2', 'Henry');
insert into Customers values ('3', 'Sam');
insert into Customers values ('4', 'Max');

insert into Orders values ('1', '3');
insert into Orders values ('2', '1');

Q:查询用户总表中没有订购记录的用户
A:从不订购 = 用户总表 - 订购过用户,NOT EXISTS

select id, name
	from Customers C
    where not exists (select *	
						  from Orders O
						  where C.id = O.customerid);

197 上升的温度

  • 创表
create table Weather
 (id int,
  recorddate date,
  temperature int);
  
insert into Weather values (1, '2015-01-01', 10);
insert into Weather values (2, '2015-01-02', 25);
insert into Weather values (3, '2015-01-03', 20);
insert into Weather values (4, '2015-01-04', 30);

Q:查询与昨天/过去最近一天相比,温度升高的日期
A:对应时间轴连续时间轴不连续解法

  1. 时间轴连续
  • EXISTS
select W1.id
	from Weather W1
    where exists (select *
					  from Weather W2
                      where W1.recorddate = W2.recorddate + 1
                      and W1.temperature > W2.temperature);
  • 自连接
select W1.id
	from Weather W1, Weather W2
    where W1.recorddate = W2.recorddate + 1
    and W1.temperature > W2.temperature;
  • DATEDIFF()
select W1.id
	from Weather W1, Weather W2
    where W1.temperature > W2.temperature
    and datediff(W1.recorddate, W2.recorddate) = 1;
  1. 时间轴不连续
  • EXISTS,引入W3.recorddate与W1.recorddate的关系
select W1.id
	from Weather W1
	where exists (select * 
					  from Weather W2
					  where W1.temperature > W2.temperature
                      and W2.recorddate = (select max(W3.recorddate)
											   from Weather W3
                                               where W1.recorddate > W3.recorddate));
  • 自连接
select W1.id
	from Weather W1, Weather W2
    where W1.temperature > W2.temperature
    and W2.recorddate = (select max(W3.recorddate)
							 from Weather W3
                             where W1.recorddate > W3.recorddate);

511 & 512 游戏玩法分析

  • 创表
create table Activity
(player_id int,
 device_id int,
 event_date date,
 games_played int,
 primary key (player_id, event_date));
 
insert into Activity values (1, 2, '2016-03-01', 5);
insert into Activity values (1, 2, '2016-05-02', 6);
insert into Activity values (2, 3, '2017-06-25', 1);
insert into Activity values (3, 1, '2016-03-02', 0);
insert into Activity values (3, 4, '2018-07-03', 5);

Q:查询每个用户最早登陆时间
A:MIN()

select player_id, min(event_date) as first_login
	from Activity
    group by player_id;

Q:查询每个用户最早“打开游戏”的时间
A:需要筛选 games_played 大于0

select player_id, min(event_date) as first_login
	from Activity
    where games_played > 0
    group by player_id;

Q:查询每个玩家首次登陆的设备名称
A:子查询 / 视图

  • 子查询,筛选 event_date
select player_id, device_id
	from Activity A1
    where event_date = (select min(event_date)
							from Activity A2
                            where A1.player_id = A2.player_id
                            group by A2.player_id);
  • 临时表
select A1.player_id, A1.device_id
	from Activity A1 inner join (select player_id, min(event_date) as first_date
									 from Activity
									 group by player_id) A2
    on A1.player_id = A2.player_id
    and A1.event_date = A2.first_date;

577 员工奖金

  • 创表
create table Employee
(empId int,
 name varchar(20),
 supervisor int,
 salary int,
 primary key (empId));
 
create table Bonus
(empId int,
 bonus int);
 
insert into Employee values (1, 'John', 3, 1000);
insert into Employee values (2, 'Dan',  3, 2000);
insert into Employee values (3, 'Brad', null, 4000);
insert into Employee values (4, 'Thomas', 3, 4000);

insert into Bonus values (2, 500);
insert into Bonus values (4, 2000);

Q:查询奖金不为 2000 的员工
A:需要包含 Bonus 表中未提及的员工1、3,以 Employee 为主表左连接

select name, bonus
	from Employee E left outer join Bonus B
    on B.empId = E.empId
    where B.bonus < 1000
    or B.bonus is null;   -- NULL无法用运算符比较

584 查询用户推荐人

  • 创表
create table Customer
(id int,
 name varchar(10),
 referee_id int);
 
insert into Customer values (1, 'Will', null);
insert into Customer values (2, 'Jane', null);
insert into Customer values (3, 'Alex', 2);
insert into Customer values (4, 'Bill', null);
insert into Customer values (5, 'Zack', 1);
insert into Customer values (6, 'Mark', 2);

Q:查询推荐人不是 2 的客户
A:注意 IS NULL 的记录

select name 
	from Customer 
    where referee_id <>2 
    or referee_id is null;  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值