[精讚] [會員登入]
944

【MySQL】每個類別中取前三高

一個由多層次所組成的SELECT述句

分享此文連結 //n.sfs.tw/16155

分享連結 【MySQL】每個類別中取前三高@小編過路君子
(文章歡迎轉載,務必尊重版權註明連結來源)
2023-04-11 23:22:54 最後編修
2023-04-10 15:06:36 By 過路君子
 

大家好,這裡是快忘光SQL的小編過路君子

看了看紀錄,上次寫這麼複雜的SQL已經是在一年之前

 

 

SQL 小編說常用也常用,說不常用也不常用,為什麼這麼說呢?

因為平常使用的時候就只會用基本的 SELECT 功能,什麼 sub select 根本就不會用到。

今天回來複習一下 MySQL 的 SQL 語法

 

那在開始之前,先假設我們有以下的資料表:

Table: Employee
+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| id           | int     |
| name         | varchar |
| salary       | int     |
| departmentId | int     |
+--------------+---------+

Table: Department
+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| name        | varchar |
+-------------+---------+

並且具有以下的內容:

Employee table:
+----+-------+--------+--------------+
| id | name  | salary | departmentId |
+----+-------+--------+--------------+
| 1  | Joe   | 85000  | 1            |
| 2  | Henry | 80000  | 2            |
| 3  | Sam   | 60000  | 2            |
| 4  | Max   | 90000  | 1            |
| 5  | Janet | 69000  | 1            |
| 6  | Randy | 85000  | 1            |
| 7  | Will  | 70000  | 1            |
+----+-------+--------+--------------+
Department table:
+----+-------+
| id | name  |
+----+-------+
| 1  | IT    |
| 2  | Sales |
+----+-------+

 

不考慮資料重複或並列

我們則需要輸出以下的資料:

+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT         | Max      | 90000  |
| IT         | Joe      | 85000  |
| IT         | Randy    | 85000  |
| Sales      | Henry    | 80000  |
| Sales      | Sam      | 60000  |
+------------+----------+--------+

簡單來說就是將 departmentId 轉換成對應的部門名稱,然後要將每個前三高薪水(Salary)的人列出,最後在對資料做排序。

 

直接上 SQL 語法:

SELECT c.name AS Department, a.name AS Employee, a.salary AS Salary
FROM Employee AS a
LEFT JOIN Department AS c
  ON c.id = a.departmentId
WHERE
  (
    SELECT COUNT(b.salary)
    FROM Employee AS b
    WHERE b.departmentId = a.departmentId
      AND a.salary < b.salary
  ) < 3
ORDER BY c.id, a.salary;

輸出結果就會如上方所示。

其中的 LEFT JOIN 作用就是為了要讓 Department 表裡的資料直接接在 Employee 表的後面,只有當 Department 表內的 id 和 Employee 表內的 departmentId 相同才需要做串接。

而比較重要的就是 WHERE 內的 sub select 了,此 sub select 會試著去統計在 Employee 表內目前有幾個人的薪水大於目前所執行到人的薪水。

而最後的小於三則是取前三高,如果要取前五高就改成 5 即可。

 

考慮資料重複或並列

若需考慮資料重複,那我們要輸出的資料變成如下:

+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT         | Max      | 90000  |
| IT         | Joe      | 85000  |
| IT         | Randy    | 85000  |
| IT         | Will     | 70000  |
| Sales      | Henry    | 80000  |
| Sales      | Sam      | 60000  |
+------------+----------+--------+

這應該才算是比較常用到的手段,總之寫法如下:

SELECT c.name AS Department, a.name AS Employee, a.salary AS Salary
FROM Employee AS a
LEFT JOIN Department AS c
  ON c.id = a.departmentId
WHERE
  (
    SELECT COUNT(b.salary)
    FROM (SELECT DISTINCT d.departmentId, d.salary FROM Employee AS d) AS b
    WHERE b.departmentId = a.departmentId
      AND a.salary < b.salary
  ) < 3;
ORDER BY c.id, a.salary;

 

只需要改一行就可以了。

簡單來說,在開始找有幾個人薪水大於目前的人之前,先把要比較的表去除重複的資料,這樣統計的時候也不會重複統計啦。

 

 

 

後記

總之這次寫完感覺這個 SQL 很有用,所以就在這邊留存一份,省的未來在那邊推敲半天。

END

你可能感興趣的文章

【CoreProtect】自行升級至 Minecraft 1.21.x、1.22.x 或更高版本 不知道為什麼,官方竟然無預警停止更新,我們只好自行救濟

【C++】使用SFML創建新視窗和新增圖標(ICON)並隱藏DOS 筆記,怕自己以後忘記怎麼創建並開啓一個新視窗

【無料版模】﹝CSS&HTML﹞製作epub電子書版模免費下載&附使用教學 一個專門用來製作epub的簡單CSS檔案,基本上已經可以做出一本還不錯的電子書,讓妳的電子書不在只有預設的字體、樣式

【C】〔無條件捨去〕如何忽略float數據 直接儲存成int型態(數據100%不失真) a148: You Cannot Pass?! 解題時所意外研究出來的神奇寫法,懂了原理之後要自行改寫成四捨五入或無條件進位應該就簡單了吧!

【Nexus Repository Manager】(deploy)使他人可以對遠端資料庫做讀寫 使用 Nexus Repository Manager 來讓各個工程師控制自己的 Jar 包,不會有 Github Merge Crashed 問題。

【Arduino/LinkIt 7697】實作小小的 MQTT Publish & Subscribe 若是要多點對多點傳輸資料,那使用 MQTT 即可快速的達成我們所需的目的

隨機好文

高捷少女:地下城的探險少女④ 耐耐突然抖了一下。「妳們聽到了嗎?」她說。「聽到什麼?」婕兒問。「那個腳步聲啊!」耐耐嚥了一下喉嚨,覺得有些害怕。「有一陣腳步聲經過,很小聲,但我還是聽到了。』「妳聽錯了吧……等等!」婕兒使終維持著將

高捷少女:耐耐的新年驚喜① 耐耐拿出手機。「我回來囉。」她說。幾分鐘後,木門緩緩打開。當它完全開啟的那一刻,小穹手中的包包掉到地上;艾米揉揉雙眼,確定自己看見的景象;婕兒的三魂七魄飛到了九霄雲外。

婕兒──她的青春① 「各位乘客,本列車即將抵達拉里奧哈自治區,並在此地停留三天兩夜,後天的中午十二點將搭乘班機返回臺灣,感謝各位乘客對本次旅程的配合。」火車上的廣播器朗誦道。「時間過得真快呢,這次的歐洲之旅就這樣結束了,

【歌評】過去の花 過去的花 ~ Fairy of Flower 彼岸花(higan bana),就是歌曲名中所指的花,而彼岸花又有「地獄花jigoku bana」的別稱,請注意,蓮台野的周圍可是長滿彼岸花呢!

艾米莉亞和高捷戀旅⑤ 「小滷,這位先生是誰呢?」果果問道。「○○!」小滷說:「他是曾經在中國四川省的國營餐廳擔任大廚的上等大廚師,是一位精通川菜的料理達人。據說學過中國料理的人,沒有一個不知道他。」