leetcode sql题练习

思路总结

 /*
 
 待更
 
 
 */

1.175. 组合两个表

题目

表1: Person

+-------------+---------+
| 列名         | 类型     |
+-------------+---------+
| PersonId    | int     |
| FirstName   | varchar |
| LastName    | varchar |
+-------------+---------+
PersonId 是上表主键

表2: Address

+-------------+---------+
| 列名         | 类型    |
+-------------+---------+
| AddressId   | int     |
| PersonId    | int     |
| City        | varchar |
| State       | varchar |
+-------------+---------+
AddressId 是上表主键

编写一个 SQL 查询,满足条件:无论 person 是否有地址信息,都需要基于上述两表提供 person 的以下信息:

FirstName, LastName, City, State

解答

select p.FirstName,p.LastName,a.City,a.State
from
person p left join address a
on
p.personid=a.personid

/*
补充:

1.数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。 在使用left jion时,on和where条件的区别如下:

- on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。

- where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。

2.where单独使用时,类似于隐式内连接,只会取两个表的公共部分。

*/

2.176. 第二高的薪水

题目

编写一个 SQL 查询,获取 Employee 表中第二高的薪水(Salary) 。

+----+--------+
| Id | Salary |
+----+--------+
| 1  | 100    |
| 2  | 200    |
| 3  | 300    |
+----+--------+

例如上述 Employee 表,SQL查询应该返回 200 作为第二高的薪水。如果不存在第二高的薪水,那么查询应返回 null

+---------------------+
| SecondHighestSalary |
+---------------------+
| 200                 |
+---------------------+

解答

--思路1-小于最大的“最大数”
select max(distinct Salary) SecondHighestSalary
from employee
where
salary<(select max(distinct salary) from employee)

--分析:
--1.对于第n大的问题,该方法不灵活。
--2.由于max会自动过滤到值为null的数据,同时如果输入都为null,则max输出也为null,因此可以保证无值的时候会输出null
--3.max是聚合函数,输入多个,输出一个

--思路2:limit x offset y

select ifNull(
(select distinct salary
from Employee 
order by Salary Desc
limit 1,1),null
) as SecondHighestSalary;
--1.limit x ,y的含义:表示从第x数据开始,读取y个。数据库中数据的记录是从0开始的。
--2.执行顺序是:order by->distinct->limit,因此不能忘记distinct的操作,如果忘记了后面的limit的操作就失效了

3.177.第N高的薪水

题目

编写一个 SQL 查询,获取 Employee 表中第 n 高的薪水(Salary)。

+----+--------+
| Id | Salary |
+----+--------+
| 1  | 100    |
| 2  | 200    |
| 3  | 300    |
+----+--------+

例如上述 Employee 表,n = 2 时,应返回第二高的薪水 200。如果不存在第 n 高的薪水,那么查询应返回 null

+------------------------+
| getNthHighestSalary(2) |
+------------------------+
| 200                    |
+------------------------+

解答

-- 思路1:
CREATE FUNCTION gehHighestSalary(N INT) RETURNS INT
BEGIN
	SET N = N - 1;
	RETURN (
	 SELECT DISTINCT salary FROM employee ORDER BY salary DESC LIMIT N, 1
	);
END

#补充
-- limit x ,y的含义:表示从第x数据开始,读取y个。数据库中数据的记录是从0开始的。
-- 2.执行顺序是:order by->distinct->limit,因此不能忘记distinct的操作,如果忘记了后面的limit的操作就失效了

-- 思路2:窗口函数

4.181. 超过经理收入的员工

题目

Employee 表包含所有员工,他们的经理也属于员工。每个员工都有一个 Id,此外还有一列对应员工的经理的 Id。

+----+-------+--------+-----------+
| Id | Name  | Salary | ManagerId |
+----+-------+--------+-----------+
| 1  | Joe   | 70000  | 3         |
| 2  | Henry | 80000  | 4         |
| 3  | Sam   | 60000  | NULL      |
| 4  | Max   | 90000  | NULL      |
+----+-------+--------+-----------+

给定 Employee 表,编写一个 SQL 查询,该查询可以获取收入超过他们经理的员工的姓名。在上面的表格中,Joe 是唯一一个收入超过他的经理的员工。

+----------+
| Employee |
+----------+
| Joe      |
+----------+

解答

select Name as Employee
from Employee as a
inner join b
on a. ManagerId=b.Id
and a.Salary>b.Salary
--a表当做经理,b表当做员工

4.182. 查找重复的电子邮箱

题目

编写一个 SQL 查询,查找 Person 表中所有重复的电子邮箱。

示例:

+----+---------+
| Id | Email   |
+----+---------+
| 1  | a@b.com |
| 2  | c@d.com |
| 3  | a@b.com |
+----+---------+

根据以上输入,你的查询应返回以下结果:

+---------+
| Email   |
+---------+
| a@b.com |
+---------+

解析

select a.Email as Email from Person a group by a.Email having count(a.Email)>=2;
-- 解析
-- 对于重复问题,第一时间要想到group by

5.183. 从不订购的客户

题目

某网站包含两个表,Customers 表和 Orders 表。编写一个 SQL 查询,找出所有从不订购任何东西的客户。

Customers 表:

+----+-------+
| Id | Name  |
+----+-------+
| 1  | Joe   |
| 2  | Henry |
| 3  | Sam   |
| 4  | Max   |
+----+-------+

Orders 表:

+----+------------+
| Id | CustomerId |
+----+------------+
| 1  | 3          |
| 2  | 1          |
+----+------------+

例如给定上述表格,你的查询应返回:

+-----------+
| Customers |
+-----------+
| Henry     |
| Max       |
+-----------+

解析

--在hive里面,on只支持等值连接,无法直接!=,但是可以等值连接了以后用where筛选
select a.Name as Customers 
from Customers a 
left join Orders b
on a.Id=b.CustomerId
where b.Id is null

6.196. 删除重复的电子邮箱

题目

编写一个 SQL 查询,来删除 Person 表中所有重复的电子邮箱,重复的邮箱里只保留 Id 最小 的那个。

+----+------------------+
| Id | Email            |
+----+------------------+
| 1  | john@example.com |
| 2  | bob@example.com  |
| 3  | john@example.com |
+----+------------------+
Id 是这个表的主键。

例如,在运行你的查询语句之后,上面的 Person 表应返回以下几行:

+----+------------------+
| Id | Email            |
+----+------------------+
| 1  | john@example.com |
| 2  | bob@example.com  |
+----+------------------+

提示:

  • 执行 SQL 之后,输出是整个 Person 表。
  • 使用 delete 语句。

解析

-- 两张表自连接,把p1表中的大的那个删除了
delete p1
from person p1 
inner join person p2
on p1.email=p2.email and p1.id>p2.id
posted @ 2020-10-26 19:59  depth-perception  阅读(187)  评论(0)    收藏  举报