leetcode力扣数据库SQL题目及解答(四)

文章目录

    • 262.行程和客户(困难)
    • 177.返回第N高的薪水(中等)
      • 思路1:order by + limit + min
      • 思路2:ifnull+自连接
    • 176.第二高的薪水

262.行程和客户(困难)

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

题解:

select t.Request_at as Day,
    round(sum(if (t.Status = 'completed', 0,1))/count(t.Status),2) as 'Cancellation Rate' # 此处别名为两个单词,需加单引号,否则会报错
from Trips t
join Users u1 on t.Client_Id = u1.Users_Id 
join Users u2 on t.Client_Id = u2.Users_Id 
where u1.Banned = 'No' 
    and u2.Banned = 'No' 
    and t.Request_at between '2013-10-01' and '2013-10-03'
group by t.Request_at # 这个容易忘记

177.返回第N高的薪水(中等)

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

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

思路1:order by + limit + min

使用降序排序并且limit N就可以得到Top N,然后选择最小的那一个就是第N名啦。

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
    RETURN (
        select(
            case
            when N=0 then 
                NULL
            when N > (select count(distinct Salary) from Employee) then 
                NULL
            else 
                (select min(e.salary) from
                    (select distinct Salary from Employee order by Salary desc limit N) e
                )  
            END   
        )
    );
END

思路2:ifnull+自连接

这种有参数的问题,我也是第一次碰到,看到别人的解法都是创造函数,就试着用了一下,记住就可以了。重点是如何选择第N名。

自连接查询真的太强大了,太好用了,搞定排名分分钟的事情,屡试不爽!

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
    RETURN
    (
        select ifnull(e1.Salary,null) as getNthHighestSalary
        from Employee e1
        left join Employee e2
        on e1.Salary  <= e2.Salary 
        group by e1.Salary
        having count(distinct e2.Salary)=N
    );
    end  

176.第二高的薪水

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

select ifnull (
    (select distinct Salary  from Employee
    order by Salary DESC
    limit 1,1),null
) as SecondHighestSalary

你可能感兴趣的:(SQL,sql,leetcode,mysql)