mysql學習筆記(4)

4.1 MySQL 實戰

學習內容

數據導入導出
將之前創建的任意一張MySQL表導出,且是CSV格式
在這裏插入圖片描述
在這裏插入圖片描述
關於csv文件,navicat for mysql中不包含cav文件的格式。嘗試用MySQL workbench,可以導出csv文件。
在這裏插入圖片描述
在這裏插入圖片描述
再將CSV表導入數據庫
在這裏插入圖片描述
使用sql語句:
導出

/*
字段之間以逗號分隔;字符串以半角雙引號包圍,字符串本身的雙引號用兩個雙引號表示。
數據行之間以\r\n分隔;
*/
select * from test_info 
into outfile 'test.csv' 
fields terminated by ',' optionally enclosed by '"' escaped by '"' 
lines terminated by '\r\n'; 

導入

load data infile 'test.csv' 
into table test_info  
fields terminated by ','  optionally enclosed by '"' escaped by '"' 
lines terminated by '\r\n'; 

作業

項目七: 各部門工資最高的員工(難度:中等)

創建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 部門有最高工資。

    USE test
CREATE TABLE IF NOT EXISTS Employee(
	Id INT UNSIGNED AUTO_INCREMENT,
	Name VARCHAR(100) NOT NULL,
	Salary INT DEFAULT 0,
  DepartmentId INT DEFAULT 0,
	PRIMARY KEY (Id)
);
INSERT INTO Employee(Name,Salary,DepartmentId) 
VALUES('Joe',70000,1),
      ('Henry',80000,2),
			('Sam',60000,2),
     	('Max',90000,1);
USE test
CREATE TABLE IF NOT EXISTS Department(
	Id INT UNSIGNED AUTO_INCREMENT,
	Name VARCHAR(100) NOT NULL,
	PRIMARY KEY (Id)
);
INSERT INTO Department(Name) 
VALUES('IT'),
     	('Sales');
select d.Name as Department,e.Name as Employee,e.Salary
from Department d,Employee e
where e.DepartmentId=d.Id and e.Salary=(Select max(Salary) from Employee where DepartmentId=d.Id)

篩選結果

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

項目八: 換座位(難度:中等)

小美是一所中學的信息科技老師,她有一張 seat 座位表,平時用來儲存學生名字和與他們相對應的座位 id。
其中縱列的 id 是連續遞增的
小美想改變相鄰倆學生的座位。
你能不能幫她寫一個 SQL query 來輸出小美想要的結果呢?
請創建如下所示seat表:
示例:

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

假如數據輸入的是上表,則輸出結果如下:

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

注意:
如果學生人數是奇數,則不需要改變最後一個同學的座位。

USE test
CREATE TABLE IF NOT EXISTS Seat(
	id INT UNSIGNED AUTO_INCREMENT,
	student VARCHAR(100) NOT NULL,
	PRIMARY KEY (id)
);
INSERT INTO Seat(student) 
VALUES('Adbot'),('Doris'),('Emerson'),('Green'),('James');
select s.id , s.student from  
(  
select id-1 as id ,student from seat where mod(id,2)=0  
union  
select id+1 as id,student from seat where mod(id,2)=1 and id !=(select count(*) 			from seat)  
union  
select id,student from seat where mod(id,2)=1 and id = (select count(*) from seat)  
) s order by id;  

項目九: 分數排名(難度:中等)
編寫一個 SQL 查詢來實現分數排名。如果兩個分數相同,則兩個分數排名(Rank)相同。請注意,平分後的下一個名次應該是下一個連續的整數值。換句話說,名次之間不應該有“間隔”。
創建以下score表:

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

sql語句

USE test
CREATE TABLE IF NOT EXISTS Scores(
	Id INT UNSIGNED AUTO_INCREMENT,
	Score FLOAT(5,2) NOT NULL,
	PRIMARY KEY (Id)
);
INSERT INTO Scores(Score) 
VALUES(3.50),(3.65),(4.00),(3.85),(4.00),(3.65);
select Score,
(select count(distinct Score) from Scores as s2 where s2.Score >= s1.Score) Rank 
from Scores as s1
order by Score DESC;

4.2 MySQL 實戰 - 複雜項目

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

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

sql語句

USE test
CREATE TABLE IF NOT EXISTS Users(
	Users_Id INT DEFAULT 0,
	Banned VARCHAR(100) NOT NULL,
	Role ENUM('client','driver','partner') DEFAULT 'client'
);
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');
SELECT Request_at Day, 
ROUND(COUNT(IF(Status != 'completed', TRUE, NULL)) / COUNT(*), 2) 'Cancellation Rate' 
            FROM Trips 
            WHERE (Request_at between '2013-10-01' and '2013-10-03') and Client_Id IN (SELECT Users_Id FROM Users WHERE Banned = 'No') 
            GROUP BY Request_at;

項目十一:各部門前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高工資的員工功能。

SELECT P2.Name AS Department,P3.Name AS Employee,P3.Salary AS Salary
FROM Employee AS P3
INNER JOIN Department AS P2
ON P2.Id = P3.DepartmentId 
WHERE (
    SELECT COUNT(DISTINCT Salary)
    FROM Employee AS P4
    WHERE P3.DepartmentId = P4.DepartmentId
    AND P4.Salary >= P3.Salary
) <= 3
ORDER BY DepartmentId,Salary DESC

項目十二 分數排名 - (難度:中等)
依然是昨天的分數表,實現排名功能,但是排名是非連續的,如下:

Score Rank
4.00 1
4.00 1
3.85 3
3.65 4
3.65 4
3.50 6

sql語句

SELECT Score,
			(SELECT COUNT(Score)
				FROM score AS s2 
				WHERE s2.Score > s1.Score
			)+1  AS rank
FROM score AS s1
ORDER BY Score DESC; 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章