2番目に高い給料&N番目に高い給料

3569 ワード

問題1:
SQLクエリーを作成し、Employeeテーブルの2番目に高い給料(Salary)を取得します.
Employeeテーブル
Id
Salary
1
100
2
200
3
300
たとえば、上記のEmployeeテーブルでは、SQLクエリは2番目に高い給料として200を返す必要があります.2番目に高い給料が存在しない場合は、クエリはnullを返します.
クエリの結果:
SecondHighestSalary
200
ソース:力ボタン(LeetCode)リンク:https://leetcode-cn.com/problems/second-highest-salary
問題の解法:
SELECT
	( SELECT DISTINCT Salary FROM Employee ORDER BY Salary DESC LIMIT 1, 1 ) AS SecondHighestSalary

なぜDISTINCTを使うのですか?
給料が同じ場合、給料を得るべきではありません.では、今同じ給料のデータを合成してデータを処理する必要があります.ここで補足します
mysqlの実行順序:
mysqlがsqlを実行する順番Fromから始まり、以下が実行する順番の流れです
  • FROM table 1 left join table 2 on table 1とtable 2のデータをデカルト積で生成し、Temp 1
  • を生成する
  • JOIN table 2ですので、まず確定表、更に関連条件
  • を確定します.
  • ON table1.column = table2.columuはテーブルのバインド条件を決定してTemp 1から中間テーブルTemp 2
  • を生成する
  • WHEREは、中間テーブルTemp 2が生成する結果をフィルタリングして中間テーブルTemp 3
  • を生成する.
  • GROUP BYは、中間テーブルTemp 3をグループ化し、中間テーブルTemp 4
  • を生成する.
  • HAVINGパケット後のレコードを集約する中間テーブルTemp 5
  • を生成する.
  • SELECTは中間表Temp 5を列選別し、中間表Temp 6
  • を生成する.
  • DISTINCTは中間表Temp 6を重量除去し、中間表Temp 7
  • を生成する.
  • ORDER BYは、Temp 7のデータをソートし、中間テーブルTemp 8
  • を生成する.
  • LIMITは中間表Temp 8をページングし、中間表Temp 9
  • を生成する.DISTINCTORDER BYおよびLIMITの前に実行されるので、mysqlがソートおよび取得された本数操作を行うと、同じ給料が1つに合成され、再操作される.
    問題2:
    SQLクエリーを作成し、Employeeテーブルのn番目に高い給料(Salary)を取得します.
    Employeeテーブル
    Id
    Salary
    1
    100
    2
    200
    3
    300
    たとえば、上記のEmployeeテーブルでは、n=2の場合、2番目に高い給料200を返します.n番目に高い給料が存在しない場合は、クエリはnullを返します.
    クエリの結果:
    getNthHighestSalary(2)
    200
    ソース:力ボタン(LeetCode)リンク:https://leetcode-cn.com/problems/nth-highest-salary
    問題2の解法:
    CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
    BEGIN
        SET N := N-1;
      RETURN (
          # Write your MySQL query statement below.
          select * from 
          (SELECT 
                distinct salary
          FROM 
                employee
          ORDER BY 
                salary DESC
          LIMIT N, 1
          ) as `getNthHighestSalary(N)`
      );
    END
    

    ここではmysqlへの関数を用いて処理する必要があり,ここでNは関数のパラメータである.
  • LIMITは0から始まるので、私たちが2番目に高い給料を望んでいるときは、LIMIT 1,0、つまりLIMIT (N-1),0です.ただしmysqlでは書き込みN-1はサポートされていないので、N変数-1
    SET N := N-1;
    
  • を先に
  • distinct用法参照問題一解法の説明
  • ここでは別名getNthHighestSalary(N)を取っていますが、Nは変数ではなく、変更はありませんが、パスに成功しました.これはなぜですか.sql文ではこのように関数を呼び出すため:
    select getNthHighestSalary(2);
    
    が返す結果フィールド名は、上のselectの後ろの関数をフィールド名として直接使用します.つまり、上の関数の一番後ろのas 'getNthHighestSalary(N)'は実は卵用が全くありません(別打、ついでに、みんなに分かち合います)
  • カスタム関数を作成する方法説明
    DELIMITER $$
    DROP FUNCTION IF EXISTS genPerson$$
    CREATE FUNCTION genPerson(name varchar(20)) RETURNS varchar(50)
    BEGIN
      DECLARE str VARCHAR(50) DEFAULT '';
      SET @tableName=name;
      SET str=CONCAT('create table ', @tableName,'(id int, name varchar(20));');
      return str;
    END $$
    DELIMITER ;
    
  • DELIMITER$$定義終了子.MySQLのデフォルトの末尾文字はセミコロンですが、関数体ではセミコロンが使用される場合があります.競合を回避するには、終了子を別途定義する必要があります.
  • DROP FUNCTION IF EXISTS genPerson$$関数genPersonが既に存在する場合は削除します.
  • CREATE FUNCTION関数genPersonを作成します.関数のパラメータはnameで、戻り値はvarchar(50)です.
  • 関数体はBEGINとENDの間に置かれる.
  • DECLARE宣言変数、strタイプvarchar(50)、デフォルト値はNULLです.
  • CONCATは複数の文字列を接続します.
  • RETURNは、接合後の文字列strを返します.

  • 最后のピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッピッ