MySQL学习记录(六)—— 复杂项目实战

项目十:行程和用户(难度:困难)

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

IdClient_IdDriver_IdCity_IdStatusRequest_at
11101completed2013-10-01
22111cancelled_by_driver2013-10-01
33126completed2013-10-01
44136cancelled_by_client2013-10-01
51101completed2013-10-02
62116completed2013-10-02
73126completed2013-10-02
821212completed2013-10-03
931012completed2013-10-03
1041312cancelled_by_driver2013-10-03

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

Users_IdBannedRole
1Noclient
2Yesclient
3Noclient
4Noclient
10Nodriver
11Nodriver
12Nodriver
13Nodriver

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

DayCancellation Rate
2013-10-010.33
2013-10-020.00
2013-10-030.50
-- 创建表 Trips 并插入数据
Create table If Not Exists Trips 
(
    Id INT(5),
    Client_Id INT(5),
    Driver_Id INT(5), 
    City_Id INT(5), 
    Status ENUM('completed','cancelled_by_driver', 'cancelled_by_client'),
    Request_at varchar(50)
);
INSERT INTO Trips(Id, Client_Id, Driver_Id,City_Id, Status, Request_at)  
           VALUES
                 ('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 并插入数据
Create table If Not Exists Users 
(
    Users_Id INT(5),
    Banned VARCHAR(50), 
    Role ENUM('client', 'driver', 'partner')
);
INSERT INTO Users (Users_Id, Banned, Role)
            VALUES 
                  ('1', 'No', 'client'),
                  ('2', 'Yes', 'client'),
                  ('3', 'No', 'client'),
                  ('4', 'No', 'client'),
                  ('10', 'No', 'driver'),
                  ('11', 'No', 'driver'),
                  ('12', 'No', 'driver'),
                  ('13', 'No', 'driver');
-- 查询 2013年10月1日 至 2013年10月3日 期间非禁止用户的取消率
SELECT request_at,
       ROUND(SUM(CASE WHEN Status="completed" THEN 0 ELSE 1 END)/COUNT(*),2) 
       AS Cancellation_Rate
    FROM 
    (
      SELECT * FROM Trips 
          WHERE client_id NOT IN
          (
            SELECT users_id FROM Users 
            WHERE banned = "yes" and role = "client"
           ) 
          AND request_at >= "2013-10-01" 
          AND request_at <= "2013-10-03"
    ) AS t
    GROUP BY request_at 
    ORDER BY request_at ASC;

在这里插入图片描述

项目十一:各部门前3高工资的员工(难度:中等)

将项目七中的 employee 表清空,重新插入以下数据(其实是多插入5,6两行):

IdNameSalaryDepartmentId
1Joe700001
2Henry800002
3Sam600002
4Max900001
5Janet690001
6Randy850001

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

DepartmentEmployeeSalary
ITMax90000
ITRandy85000
ITJoe70000
SalesHenry80000
SalesSam60000

此外,请考虑实现各部门前N高工资的员工功能。

-- 删除之前创建的 Employee 表的数据,重新插入数据
TRUNCATE TABLE Employee;
INSERT INTO Employee(Id, Name, Salary, DepartmentId)
              VALUES
                    (1, "Joe", 70000, 1),
                    (2, "Henry", 80000, 2),
                    (3, "Sam", 60000, 2),
                    (4, "Max", 90000, 1),
                    (5, "Janet", 69000, 1),
                    (6, "Randy", 85000, 1);
-- 将两个表按照部门编号进行内联结保存为新表 h ,再根据部门分组找出前三高的工资
CREATE TABLE h AS
    SELECT d.Name Department, e.Name Employee, e.Salary 
        FROM Employee e INNER JOIN Department d
            ON e.DepartmentId = d.Id;
SELECT Department, h1.Employee, h1.Salary
    FROM h h1
    WHERE 3 >   
           (
            SELECT COUNT(DISTINCT h2.Salary) 
            FROM h h2
            WHERE h2.Salary > h1.Salary AND h1.Department = h2.Department
            )
    ORDER BY Department, h1.Salary DESC;

在这里插入图片描述

项目十二 分数排名 - (难度:中等)

依然是项目九的分数表,实现排名功能,但是排名是非连续的,如下:

ScoreRank
4.001
4.001
3.853
3.654
3.654
3.506
-- 创建score表并插入数据
CREATE TABLE score
(
	Id INT(10) PRIMARY KEY,
	Score FLOAT(4)
);
INSERT INTO score(Id, Score)
           VALUES(1, 3.50),
                 (2, 3.65),
                 (3, 4.00),
                 (4, 3.85),
                 (5, 4.00),
                 (6, 3.65);
```sql
-- 创建score表并插入数据
CREATE TABLE score
(
	Id INT(10) PRIMARY KEY,
	Score FLOAT(4)
);
INSERT INTO score(Id, Score)
           VALUES(1, 3.50),
                 (2, 3.65),
                 (3, 4.00),
                 (4, 3.85),
                 (5, 4.00),
                 (6, 3.65);
-- 用左联结,条件是左表的分数小于右表的分数,根据id分组后,统计右表分数的个数并+1
SELECT s1.Score, COUNT(s2.Score) + 1 Rank
    FROM Score s1 LEFT JOIN Score s2
        ON s1.Score < s2.Score
    GROUP BY s1.Id
    ORDER BY s1.Score DESC;

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值