河南南阳收割机被堵事件:官员缺德,祸患无穷

极目新闻领导公开“记者毕节采访被打”细节:他们打人后擦去指纹

突发!员工跳楼!只拿低保工资!央企设计院集体罢工!

退休后的温家宝

突发!北京某院集体罢工!

生成图片,分享到微信朋友圈

自由微信安卓APP发布,立即下载! | 提交文章网址
查看原文

LeetCode上的8个SQL问题,测测你会几个

糖甜甜甜 DataGo数据狗 2022-07-01


   LeetCode上的8个SQL问题


 1.

换座位


小美是一所中学的信息科技老师,她有一张 seat 座位表,平时用来储存学生名字和与他们相对应的座位 id。

其中纵列的 id 是连续递增的。

小美想改变相邻俩学生的座位。

你能不能帮她写一个 SQL query 来输出小美想要的结果呢?

示例:

+---------+---------+ | id | student | +---------+---------+ | 1 | Abbot | | 2 | Doris | | 3 | Emerson | | 4 | Green | | 5 | Jeames | +---------+---------+

假如数据输入的是上表,则输出结果如下:

+---------+---------+ | id | student | +---------+---------+ | 1 | Doris | | 2 | Abbot | | 3 | Green | | 4 | Emerson | | 5 | Jeames | +---------+---------+

注意:

如果学生人数是奇数,则不需要改变最后一个同学的座位。

MySQL代码:

1set @n=(select count(idfrom seat);
2select @m:=if(id=@n&&mod(@n,2)=1,id,if(mod(id,2)=0,id-1,id+1)) as id,student 
3from seat, (select @m:=-1) b ORDER BY id ASC


 2.

第N高的薪水


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

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

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

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

MySQL代码:

1CREATE FUNCTION getNthHighestSalary(N INTRETURNS INT
2BEGIN
3  DECLARE m int;
4  set @i=0;
5  SELECT b.salary into m from (SELECT a.salary,@i:=@i+1 as rown 
6  from (SELECT DISTINCT(salary) from employee ORDER BY salary DESC) a) b 
7  WHERE b.rown=N;
8  RETURN m;
9END;
10
11select getNthHighestSalary(2);


 3.

分数排名


编写一个 SQL 查询来实现分数排名。如果两个分数相同,则两个分数排名(Rank)相同。请注意,平分后的下一个名次应该是下一个连续的整数值。换句话说,名次之间不应该有“间隔”。

+----+-------+ | Id | Score | +----+-------+ | 1 | 3.50 | | 2 | 3.65 | | 3 | 4.00 | | 4 | 3.85 | | 5 | 4.00 | | 6 | 3.65 | +----+-------+

例如,根据上述给定的 Scores 表,你的查询应该返回(按分数从高到低排列):

+-------+------+ | Score | Rank | +-------+------+ | 4.00 | 1 | | 4.00 | 1 | | 3.85 | 2 | | 3.65 | 3 | | 3.65 | 3 | | 3.50 | 4 | +-------+------+

MySQL代码:

1SELECT m.Score, (SELECT count(t.Score)+1 from 
2(SELECT s.Score,count(s.Score) from scores s GROUP BY Score ORDER BY Score DESC) t 
3WHERE t.Score>m.Score) Rank 
4FROM scores m 
5ORDER BY m.Score DESC


 4.

连续出现的数字


编写一个 SQL 查询,查找所有至少连续出现三次的数字。

+----+-----+ | Id | Num | +----+-----+ | 1 | 1 | | 2 | 1 | | 3 | 1 | | 4 | 2 | | 5 | 1 | | 6 | 2 | | 7 | 2 | +----+-----+

例如,给定上面的 Logs 表, 1 是唯一连续出现至少三次的数字。

+-----------------+ | ConsecutiveNums | +-----------------+ | 1 | +-----------------+

MySQL代码:

1SELECT cast(DISTINCT(t.Num) as ) ConsecutiveNums 
2FROM (SELECT os.Num, @Rank:=IF(@pre=os.Num,@Rank+1,1Rank,@pre:=os.Num 
3from (SELECT Num FROM `logs` ORDER BY Num DESCas os,(SELECT @Rank:=0,@pre:=-1as init) as t WHERE t.Rank>3


 5.

部门工资最高的员工


Employee 表包含所有员工信息,每个员工有其对应的 Id, salary 和 department Id。

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

Department 表包含公司所有部门的信息。

+----+----------+ | Id | Name | +----+----------+ | 1 | IT | | 2 | Sales | +----+----------+

编写一个 SQL 查询,找出每个部门工资最高的员工。例如,根据上述给定的表格,Max 在 IT 部门有最高工资,Henry 在 Sales 部门有最高工资。

+------------+----------+--------+ | Department | Employee | Salary | +------------+----------+--------+ | IT | Max | 90000 | | Sales | Henry | 80000 | +------------+----------+--------+

MySQL代码:

1SELECT B.Name Department,A.Name Employee,A.Salary FROM (
2    SELECT Name,Salary,DepartmentId FROM (
3    SELECT * from Employee order by DepartmentId,Salary DESC
4     ) C GROUP BY C.DepartmentId
5     ) A 
6    JOIN department B 
7    ON A.DepartmentId=B.Id


 6.

行程和用户


Trips 表中存所有出租车的行程信息。每段行程有唯一健 Id,Client_Id 和 Driver_Id 是 Users 表中 Users_Id 的外键。Status 是枚举类型,枚举成员为 (‘completed’, ‘cancelled_by_driver’, ‘cancelled_by_client’)。

+----+-----------+-----------+---------+--------------------+----------+ | Id | Client_Id | Driver_Id | City_Id | Status |Request_at| +----+-----------+-----------+---------+--------------------+----------+ | 1 | 1 | 10 | 1 | completed |2013-10-01| | 2 | 2 | 11 | 1 | cancelled_by_driver|2013-10-01| | 3 | 3 | 12 | 6 | completed |2013-10-01| | 4 | 4 | 13 | 6 | cancelled_by_client|2013-10-01| | 5 | 1 | 10 | 1 | completed |2013-10-02| | 6 | 2 | 11 | 6 | completed |2013-10-02| | 7 | 3 | 12 | 6 | completed |2013-10-02| | 8 | 2 | 12 | 12 | completed |2013-10-03| | 9 | 3 | 10 | 12 | completed |2013-10-03| | 10 | 4 | 13 | 12 | cancelled_by_driver|2013-10-03| +----+-----------+-----------+---------+--------------------+----------+

Users 表存所有用户。每个用户有唯一键 Users_Id。Banned 表示这个用户是否被禁止,Role 则是一个表示(‘client’, ‘driver’, ‘partner’)的枚举类型。

+----------+--------+--------+ | Users_Id | Banned | Role | +----------+--------+--------+ | 1 | No | client | | 2 | Yes | client | | 3 | No | client | | 4 | No | client | | 10 | No | driver | | 11 | No | driver | | 12 | No | driver | | 13 | No | driver | +----------+--------+--------+

写一段 SQL 语句查出 2013年10月1日 至 2013年10月3日 期间非禁止用户的取消率。基于上表,你的 SQL 语句应返回如下结果,取消率(Cancellation Rate)保留两位小数。

+------------+-------------------+ | Day | Cancellation Rate | +------------+-------------------+ | 2013-10-01 | 0.33 | | 2013-10-02 | 0.00 | | 2013-10-03 | 0.50 | +------------+-------------------+

MySQL代码:

1SELECT A.Request_at Day,FORMAT(SUM(A.StatusID)/count(A.Status),2'Cancellation Rate' 
2from (select Id,Client_Id,Driver_Id,Status,Request_at,IF(Status='completed',0,1) StatusID 
3from Trips 
4where (Client_Id IN (select Users_Id from Users where Banned="No" AND Role='client')) AND (Driver_Id IN (select Users_Id from Users where Banned="No" AND Role='driver'))) A 
5GROUP BY A.Request_at


 7.

体育馆的人流量


X 市建了一个新的体育馆,每日人流量信息被记录在这三列信息中:序号 (id)、日期 (date)、 人流量 (people)。

请编写一个查询语句,找出高峰期时段,要求连续三天及以上,并且每天人流量均不少于100。

例如,表 stadium

+------+------------+-----------+ | id | date | people | +------+------------+-----------+ | 1 | 2017-01-01 | 10 | | 2 | 2017-01-02 | 109 | | 3 | 2017-01-03 | 150 | | 4 | 2017-01-04 | 99 | | 5 | 2017-01-05 | 145 | | 6 | 2017-01-06 | 1455 | | 7 | 2017-01-07 | 199 | | 8 | 2017-01-08 | 188 | +------+------------+-----------+

对于上面的示例数据,输出为:

+------+------------+-----------+ | id | date | people | +------+------------+-----------+ | 5 | 2017-01-05 | 145 | | 6 | 2017-01-06 | 1455 | | 7 | 2017-01-07 | 199 | | 8 | 2017-01-08 | 188 | +------+------------+-----------+

Note:
每天只有一行记录,日期随着 id 的增加而增加。

MySQL代码:

1SELECT id,date,people from stadium,(
2    SELECT if(COUNT(id)>=3,GROUP_CONCAT(id),null) e FROM (
3          select id,date,people,(@b:=@b+1as b, id-@b as c 
4          from stadium a,(SELECT @b := 0) tmp_b 
5          where people>=100
6     ) t GROUP BY t.c
7) f WHERE f.e is not null and FIND_IN_SET(id , f.e)


 8.

部门工资前三高的员工


Employee 表包含所有员工信息,每个员工有其对应的 Id, salary 和 department Id 。

+----+-------+--------+--------------+ | Id | Name | Salary | DepartmentId | +----+-------+--------+--------------+ | 1 | Joe | 70000 | 1 | | 2 | Henry | 80000 | 2 | | 3 | Sam | 60000 | 2 | | 4 | Max | 90000 | 1 | | 5 | Janet | 69000 | 1 | | 6 | Randy | 85000 | 1 | +----+-------+--------+--------------+

Department 表包含公司所有部门的信息。

+----+----------+ | Id | Name | +----+----------+ | 1 | IT | | 2 | Sales | +----+----------+

编写一个 SQL 查询,找出每个部门工资前三高的员工。例如,根据上述给定的表格,查询结果应返回:

+------------+----------+--------+ | Department | Employee | Salary | +------------+----------+--------+ | IT | Max | 90000 | | IT | Randy | 85000 | | IT | Joe | 70000 | | Sales | Henry | 80000 | | Sales | Sam | 60000 | +------------+----------+--------+

MySQL代码:

1SELECT D1.Name Department, E1.Name Employee,  E1.Salary
2FROM Employee E1, Employee E2, Department D1
3WHERE E1.DepartmentID = E2.DepartmentID
4AND E2.Salary >= E1.Salary 
5AND E1.DepartmentID = D1.ID      
6GROUP BY E1.Name
7HAVING COUNT(DISTINCT E2.Salary) <= 3
8ORDER BY D1.Name, E1.Salary DESC


看完觉得有用就点个赞呗!

文章有问题?点此查看未经处理的缓存