MySQL 基礎4

首先放張圖,以便於自己日後查看複習,該圖來自如下鏈接:
https://blog.csdn.net/y3329223/article/details/88084323
 內連接與外連接的介紹和區別

項目十六 分數排名 (難度:中等)

依然是昨天的分數表,實現排名功能,但是排名需要是非連續的,如下:
±------±-----+
| Score | Rank |
±------±-----+
| 4.00 | 1 |
| 4.00 | 1 |
| 3.85 | 3 |
| 3.65 | 4 |
| 3.65 | 4 |
| 3.50 | 6 |
±------±-----

DROP TABLE IF EXISTS Score;

CREATE TABLE Score(
Id INT,
score DECIMAL(3,2)
);

INSERT INTO Score VALUES(1,3.65);
INSERT INTO Score VALUES(2,3.50);
INSERT INTO Score VALUES(3,4.00);
INSERT INTO Score VALUES(4,3.85);
INSERT INTO Score VALUES(5,3.65);
INSERT INTO Score VALUES(6,4.00);

SELECT score,
CASE 
WHEN @pre_score = score THEN @rank_tmp
WHEN @pre_score:=score THEN @rank_tmp:=@rank_tmp+1
END AS 'rank'
FROM score,(SELECT @rank_tmp:=0,@pre_score:=NULL) tmp
ORDER BY
score.score DESC;

結果如下;
在這裏插入圖片描述
參考:
https://www.cnblogs.com/sunchaothu/p/10467361.html

項目十七:查詢回答率最高的問題 (難度:中等)

求出survey_log表中回答率最高的問題,表格的字段有:uid, action, question_id, answer_id, q_num, timestamp
uid是用戶id;action的值爲:“show”, “answer”, “skip”;當action是"answer"時,answer_id不爲空,相反,當action是"show"和"skip"時爲空(null);q_num是問題的數字序號。
寫一條sql語句找出回答率最高的問題。
舉例:
輸入

12345678 ±-----±----------±-------------±-----------±----------±-----------+| uid | action | question_id | answer_id | q_num | timestamp |±-----±----------±-------------±-----------±----------±-----------+| 5 | show | 285 | null | 1 | 123 || 5 | answer | 285 | 124124 | 1 | 124 || 5 | show | 369 | null | 2 | 125 || 5 | skip | 369 | null | 2 | 126 |±-----±----------±-------------±-----------±----------±-----------+

輸出

12345 ±------------+| survey_log |±------------+| 285 |±------------+

說明
問題285的回答率爲1/1,然而問題369的回答率是0/1,所以輸出是285。
注意: 最高回答率的意思是:同一個問題出現的次數中回答的比例。

創建表:
DROP TABLE IF EXISTS survey_log;

CREATE TABLE survey_log(
uid INT, 
action VARCHAR(50), 
question_id INT, 
answer_id INT, 
q_num INT, 
timestamp INT
);
插入數據:
INSERT INTO survey_log VALUES(5, 'show', 285, NULL, 1,123);
INSERT INTO survey_log VALUES(5, 'answer', 285, 124124, 1,124);
INSERT INTO survey_log VALUES(5, 'show', 369, NULL, 2,125);
INSERT INTO survey_log VALUES(5, 'skip', 369, NULL, 2,126);

選取:
SELECT survey_log
FROM(
			SELECT t.survey_log, dense_rank() over (ORDER BY ratio DESC) as 'Rank'
			FROM(
						SELECT s.question_id as survey_log,
						(CASE
						WHEN SUM(s.action = 'answer') = 0 then 0
						else SUM(s.action = 'answer') / COUNT(*)
						END) as ratio
						FROM survey_log as s
			GROUP BY uid, question_id) as t
) as p
WHERE p.Rank = 1;

結果:
在這裏插入圖片描述

項目十八:各部門前3高工資的員工(難度:中等)

將項目7中的employee表清空,重新插入以下數據(其實是多插入5,6兩行):
±—±------±-------±-------------+
| 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 |
±—±------±-------±-------------+
編寫一個 SQL 查詢,找出每個部門工資前三高的員工。例如,根據上述給定的表格,查詢結果應返回:
±-----------±---------±-------+
| Department | Employee | Salary |
±-----------±---------±-------+
| IT | Max | 90000 |
| IT | Randy | 85000 |
| IT | Joe | 70000 |
| Sales | Henry | 80000 |
| Sales | Sam | 60000 |
±-----------±---------±-------+

此外,請考慮實現各部門前N高工資的員工功能。

DROP TABLE IF EXISTS employee;
DROP TABLE IF EXISTS department;

創建表;
CREATE TABLE Employee (
Id int, 
Name varchar(255), 
Salary int, 
DepartmentId int
);

CREATE TABLE Department (
Id int, 
Name varchar(255)
);
Truncate table Employee;

插入數據:
INSERT INTO Employee (Id, Name, Salary,DepartmentId) VALUES ('1', 'Joe', '70000', '1');
INSERT INTO Employee (Id, Name, Salary,DepartmentId) VALUES ('2', 'Henry', '80000', '2');
INSERT INTO Employee (Id, Name, Salary,DepartmentId) VALUES ('3', 'Sam', '60000', '2');
INSERT INTO Employee (Id, Name, Salary,DepartmentId) VALUES ('4', 'Max', '90000', '1');
INSERT INTO Employee (Id, Name, Salary,DepartmentId) VALUES ('1', 'Janet', '69000', '1');
INSERT INTO Employee (Id, Name, Salary,DepartmentId) VALUES ('1', 'Randy', '85000', '1');

INSERT INTO Department (Id, Name) VALUES('1', 'IT');
INSERT INTO Department (Id, Name) VALUES('2', 'Sales');

選取:
SELECT d.Name AS Department, e1.Name AS Employee, e1.Salary
FROM Employee e1 JOIN Department d ON e1.DepartmentId = d.Id
WHERE 3 > (SELECT COUNT(DISTINCT e2.Salary) FROM Employee e2
           WHERE e2.Salary > e1.Salary AND e1.DepartmentId = e2.DepartmentId);

結果:
在這裏插入圖片描述
參考:
https://www.cnblogs.com/an5456/p/10478949.html
https://blog.csdn.net/qq_40803710/article/details/80303072

項目十九:平面上最近距離

point_2d 表包含一個平面內一些點(超過兩個)的座標值(x,y)。
寫一條查詢語句求出這些點中的最短距離並保留2位小數。

x y
-1 -1
0 0
-1 -2

最短距離是1,從點(-1,-1)到點(-1,2)。所以輸出結果爲:

shortest
1.00

注意: 所有點的最大距離小於10000。

創建表:
DROP TABLE IF EXISTS Trips;

CREATE TABLE point_2d(
x INT,
y INT
);

插入數據:
INSERT INTO POINT_2d VALUES(-1,-1);
INSERT INTO POINT_2d VALUES(0,0);
INSERT INTO POINT_2d VALUES(-1,-2);

選取:
SELECT MIN(distance) as shortest
FROM(
			SELECT POW ((p1.x - p2.x),2) + POW((p1.y - p2.y), 2)  as distance
			FROM point_2d as p1
			INNER JOIN point_2d as p2
			ON !(p1.x = p2.x and p1.y = p2.y)
) as p;

結果:
在這裏插入圖片描述

項目二十:行程和用戶(難度:困難)

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 |
±-----------±------------------+

創建表:
DROP TABLE IF EXISTS Trips;
DROP TABLE IF EXISTS Users;

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
    Request_at AS DAY,
    ROUND( SUM( CASE WHEN `Status` LIKE 'cancelled%' THEN 1 ELSE 0 END ) / COUNT( * ), 2 ) AS cancelled_rate 
FROM
    trips
    LEFT JOIN ( SELECT Users_Id, Banned FROM users ) client ON trips.Client_Id = client.Users_Id
    LEFT JOIN ( SELECT Users_Id, Banned FROM users ) driver ON trips.Driver_Id = driver.Users_Id
    WHERE client.Banned = 'NO' AND driver.Banned = 'NO'
    GROUP BY Request_at
    ORDER BY Request_at;

結果:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章