DataWhale 組隊學習MySQL 任務四 正在做。。。

 

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

依然是昨天的分數表,實現排名功能,但是排名需要是非連續的,如下:

+-------+------+

| Score | Rank |

+-------+------+

| 4.00 | 1 |

| 4.00 | 1 |

| 3.85 | 3 |

| 3.65 | 4 |

| 3.65 | 4 |

| 3.50 | 6 |

+-------+------

 

 

 

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

求出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語句找出回答率最高的問題。

舉例:

輸入

1

2

3

4

5

6

7

8

+------+-----------+--------------+------------+-----------+------------+

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

+------+-----------+--------------+------------+-----------+------------+

輸出

1

2

3

4

5

+-------------+

| survey_log |

+-------------+

| 285 |

+-------------+

說明

問題285的回答率爲1/1,然而問題369的回答率是0/1,所以輸出是285。

注意: 最高回答率的意思是:同一個問題出現的次數中回答的比例。

 

 

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

 

 

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

point_2d 表包含一個平面內一些點(超過兩個)的座標值(x,y)。

寫一條查詢語句求出這些點中的最短距離並保留2位小數。

x

y

-1

-1

0

0

-1

-2

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

shortest

1.00

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

 

 

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

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 |

+------------+-------------------+

 

答案,來自官方

 

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

根據question_id分組,然後根據回答率降序排序,並輸出第一條記錄。回答率就是action字段中’answer’的次數除以’show’的次數。要計算回答率,就需要統計action中’answer’和’show’的個數。可以根據question_id分組,然後分別統計出每道題’answer’和’show’的次數。

首先,按question_id分組,然後用SUM()和IF()統計每道題’answer’和’show’的次數:

1

2

3

4

SELECT question_id,

SUM(IF(action='show', 1, 0)) AS num_show,

SUM(IF(action='answer', 1, 0)) AS num_answer

FROM survey_log GROUP BY question_id

再按question_id分組,並根據回答率降序排序:

1

2

3

4

5

6

SELECT question_id AS survey_log FROM

(SELECT question_id,

SUM(IF(action='show', 1, 0)) AS num_show,

SUM(IF(action='answer', 1, 0)) AS num_answer

FROM survey_log GROUP BY question_id) AS t

ORDER BY (num_answer/num_show) DESC;

最後輸出第一條記錄:

1

2

3

4

5

6

SELECT question_id AS survey_log FROM

(SELECT question_id,

SUM(IF(action='show', 1, 0)) AS num_show,

SUM(IF(action='answer', 1, 0)) AS num_answer

FROM survey_log GROUP BY question_id) AS t

ORDER BY (num_answer/num_show) DESC LIMIT 1;

 

項目十八 各部門工資第三高的員工

思路一: 因爲只有兩個部門,我們可以取巧分別對每個部門按工資降序排名,取前三行,然後UNION。

需要注意的是,ORDER BY 和 LIMIT本身不支持在子查詢中使用。所以需要加上括號形成獨立的幾個表而不是UNION的子查詢。

 

思路二:也是大家普遍在網上搜到的答案。

和分數排名的思想類似,用到了輔助表。

emp1是我們的基礎表,emp2是輔助表。

將emp1裏的每個salary和整張emp2比較。下面來捋下過程。

以IT部門爲例,emp1的salary有 6.9萬,7萬,8.5萬,9萬四個數

① emp1工資是6.9萬的時候,emp2表裏的 count是3,說明有三個大於它的(間接說明它是第四大)

② emp1工資是7萬的時候,emp2表裏的count是2,說明有兩個大於它的(間接說明它是第三大)

③emp1工資是8.5萬的時候,emp2表裏的count是1,說明有1個大於它的(間接說明它是第二大)

④emp1工資是9萬的時候,emp2表裏的count是0,說明沒有大於它的(間接說明它是最大的)

在code裏就是emp2.Salary > (emp1.Salary =6.9)

 

然後我們要求的是前三大,所以是COUNT() < 3。

 

 

 

 

 

 

項目十九 平面上最近距離

 

連接(join)兩張 point_2d 表生成所有可能的點對,然後計算距離,求最小距離並保留小數點後2位。

1

2

3

SELECT ROUND(SQRT(MIN(POW(p1.x-p2.x,2)+POW(p1.y-p2.y,2))),2) AS shortest

FROM point_2d AS p1, point_2d AS p2

WHERE p1.x <> p2.x OR p1.y <> p2.y;

 

項目二十 行程和用戶

題目意思本身很簡單,難點在於如何同時計算取消的數量和總數量。

總數量很簡單,就是COUNT(*),

同時計算取消數量可以用SUM(CASE END)來實現。對status列計算數量,如果是cancel就記1,complete記爲0.

 

P.S. 如果需要userID 匹配 clientID和driverID兩列,需要寫兩個Lef Join。 但是可以通過CASE ...END 在最終結果只顯示一列。

 

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