天天看點

LeetCode(資料庫)- 第N高的薪水

題目連結:​​點選打開連結​​

題目大意:略。

解題思路:

  • 解決方案 (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