題目連結:點選打開連結
題目大意:略。
解題思路:
- 解決方案 (1):單表查詢、Limit
- 解決方案 (2):子查詢、算出每個目前薪水不被超過其他薪水的個數就是它的排名(目前:指的是 FROM 的表的 salary)
- 解決方案 (3):自連接配接(或笛卡兒積)、和解決方案(2)思路一樣,目前薪水不被超過其他薪水的個數就是它的排名(目前:分組裡的表 salary)
- 解決方案 (4):自定義變量、先按照 salary 降序,再類似 for 循環羅列好每個的薪水的排名就能最後求出第N個薪水的答案;這裡 FROM 後面的 init 隻是個表别名,為了初始化資料罷了
- 解決方案 (5):視窗函數、思路和解決方案(4)一樣,隻是借用函數來解決
注意:【視窗函數】
實際上,在mysql8.0中有相關的内置函數,而且考慮了各種排名問題:
row_number(): 同薪不同名,相當于行号,例如3000、2000、2000、1000排名後為1、2、3、4
rank(): 同薪同名,有跳級,例如3000、2000、2000、1000排名後為1、2、2、4
dense_rank(): 同薪同名,無跳級,例如3000、2000、2000、1000排名後為1、2、2、3
ntile(): 分桶排名,即首先按桶的個數分出第一二三桶,然後各桶内從1排名,實際不是很常用
顯然,本題是要用第三個函數。
另外這三個函數必須要要與其搭檔over()配套使用,over()中的參數常見的有兩個,分别是
partition by,按某字段切分
order by,與正常order by用法一緻,也區分ASC(預設)和DESC,因為排名總得有個依據
注:下面代碼僅在mysql8.0以上版本可用,最新OJ已支援。
-- 解決方案 (1)
CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
SET N := N-1;
RETURN (
# Write your MySQL query statement below.
SELECT
salary
FROM
employee
GROUP BY
salary
ORDER BY
salary DESC
LIMIT N, 1
);
END
-- 解決方案 (2)
CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
RETURN (
# Write your MySQL query statement below.
SELECT
DISTINCT e.salary
FROM
employee e
WHERE
(SELECT count(DISTINCT salary) FROM employee WHERE salary>e.salary) = N-1
);
END
-- 解決方案 (3)
CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
RETURN (
# Write your MySQL query statement below.
SELECT
e1.salary
FROM
employee e1 JOIN employee e2 ON e1.salary <= e2.salary
GROUP BY
e1.salary
HAVING
count(DISTINCT e2.salary) = N
);
END
-- 解決方案 (4)
CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
RETURN (
# Write your MySQL query statement below.
SELECT
DISTINCT salary
FROM
(SELECT
salary, @r:=IF(@p=salary, @r, @r+1) AS rnk, @p:= salary
FROM
employee, (SELECT @r:=0, @p:=NULL) init
ORDER BY
salary DESC) tmp
WHERE rnk = N
);
END
-- 解決方案 (5)
CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
RETURN (
# Write your MySQL query statement below.
SELECT
DISTINCT salary
FROM
(SELECT
salary, dense_rank() over(ORDER BY salary DESC) AS rnk
FROM
employee) tmp
WHERE rnk = N
);
END