LEETCODE数据库题之困难题汇总

文章目录

  • 185. 部门工资前三高的所有员工
  • 262. 行程和用户
    • 题目
    • 解答
  • 601. 体育馆的人流量
    • 题目
    • 解答

185. 部门工资前三高的所有员工

这个题见我的另一篇博客排名类的汇总

262. 行程和用户

题目

LEETCODE数据库题之困难题汇总_第1张图片
建表语句如下

Create table If Not Exists Trips (Id int, Client_Id int, Driver_Id int, City_Id int, Status ENUM('completed', 'cancelled_by_driver', 'cancelled_by_client'), Request_at varchar(50))
Create table If Not Exists Users (Users_Id int, Banned varchar(50), Role ENUM('client', 'driver', 'partner'))
Truncate table Trips
insert into Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) values ('1', '1', '10', '1', 'completed', '2013-10-01')
insert into Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) values ('2', '2', '11', '1', 'cancelled_by_driver', '2013-10-01')
insert into Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) values ('3', '3', '12', '6', 'completed', '2013-10-01')
insert into Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) values ('4', '4', '13', '6', 'cancelled_by_client', '2013-10-01')
insert into Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) values ('5', '1', '10', '1', 'completed', '2013-10-02')
insert into Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) values ('6', '2', '11', '6', 'completed', '2013-10-02')
insert into Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) values ('7', '3', '12', '6', 'completed', '2013-10-02')
insert into Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) values ('8', '2', '12', '12', 'completed', '2013-10-03')
insert into Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) values ('9', '3', '10', '12', 'completed', '2013-10-03')
insert into Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) values ('10', '4', '13', '12', 'cancelled_by_driver', '2013-10-03')
Truncate table Users
insert into Users (Users_Id, Banned, Role) values ('1', 'No', 'client')
insert into Users (Users_Id, Banned, Role) values ('2', 'Yes', 'client')
insert into Users (Users_Id, Banned, Role) values ('3', 'No', 'client')
insert into Users (Users_Id, Banned, Role) values ('4', 'No', 'client')
insert into Users (Users_Id, Banned, Role) values ('10', 'No', 'driver')
insert into Users (Users_Id, Banned, Role) values ('11', 'No', 'driver')
insert into Users (Users_Id, Banned, Role) values ('12', 'No', 'driver')
insert into Users (Users_Id, Banned, Role) values ('13', 'No', 'driver')

解答

一开始自己笨办法粗暴的写了一个

SELECT 
    a.Request_at Day,
    CASE 
     WHEN (b.cancelled_count/a.day_count) IS NULL THEN 0.00
     ELSE ROUND(b.cancelled_count/a.day_count,2) 
    END AS `Cancellation Rate`
FROM
(SELECT
    count(Id) day_count,
    Request_at
FROM
    Trips
WHERE
        Client_Id NOT IN  
            (SELECT
                Users_Id
            FROM
                Users
            WHERE Banned = 'Yes'
            )
        AND
             Request_at >= '2013-10-01'
        AND
             Request_at <= '2013-10-03'
GROUP BY
    Request_at) a -- a表计算的是每天非禁止用户生成的订单数
LEFT JOIN
(SELECT
    COUNT(Id) cancelled_count,
    Request_at
FROM
    Trips 
WHERE
        Status IN ('cancelled_by_client', 'cancelled_by_driver')
    AND
        Client_Id NOT IN  
            (SELECT
                Users_Id
            FROM
                Users
            WHERE Banned = 'Yes'
            )
GROUP BY Request_at) b -- b表计算的是每天非禁止用户取消的订单数
ON a.Request_at=b.Request_at;

看你评论才发现原来可以这么简洁

# Write your MySQL query statement below
SELECT
    t.request_at Day,
    ROUND(COUNT(IF(t.Status != 'completed', status, null))/COUNT(t.Status), 2) AS 'Cancellation Rate'
FROM 
    Trips t
LEFT JOIN
    Users u
ON
    t.Client_Id = u.Users_Id 
WHERE 
    u.Banned != 'Yes'
AND
    t.Request_at >= '2013-10-01'
AND
    t.Request_at <= '2013-10-03'
GROUP BY Day

601. 体育馆的人流量

题目

LEETCODE数据库题之困难题汇总_第2张图片
建表语句

Create table If Not Exists stadium (id int, visit_date DATE NULL, people int)
Truncate table stadium
insert into stadium (id, visit_date, people) values ('1', '2017-01-01', '10')
insert into stadium (id, visit_date, people) values ('2', '2017-01-02', '109')
insert into stadium (id, visit_date, people) values ('3', '2017-01-03', '150')
insert into stadium (id, visit_date, people) values ('4', '2017-01-04', '99')
insert into stadium (id, visit_date, people) values ('5', '2017-01-05', '145')
insert into stadium (id, visit_date, people) values ('6', '2017-01-06', '1455')
insert into stadium (id, visit_date, people) values ('7', '2017-01-07', '199')
insert into stadium (id, visit_date, people) values ('8', '2017-01-08', '188')

解答

这里推荐这种通用的方式,技巧是根据id-row_number求了连续的子块

SELECT 
    t3.id,
    t3.visit_date,
    t3.people 
FROM (
    SELECT 
        t2.id,
        t2.visit_date,
        t2.people,
        count(*) over(partition by t2.id-t2.rk) cn 
    FROM (
        SELECT 
            t1.*,
            row_number() over() rk 
        FROM (
            SELECT * 
            FROM stadium 
            WHERE people >=100 
        ) t1 -- t1表找出大于100的数,并生成行号
    )t2 -- t2按id和rk的差聚合(如果id连续的话,id和rk的差应该相等;因为它们前面剔除的行数相等),这样可以得到连续的几个子块
)t3 
WHERE t3.cn >=3; -- 不少于3行的子块

你可能感兴趣的:(#,MySQL,数据库)