Leetcode176.第二高的薪水(簡單)

題目
編寫一個 SQL 查詢污秆,獲取 Employee 表中第二高的薪水(Salary) 劈猪。

+----+--------+
| Id | Salary |
+----+--------+
| 1  | 100    |
| 2  | 200    |
| 3  | 300    |
+----+--------+

例如上述 Employee 表,SQL查詢應(yīng)該返回 200 作為第二高的薪水良拼。如果不存在第二高的薪水战得,那么查詢應(yīng)返回 null。

+---------------------+
| SecondHighestSalary |
+---------------------+
| 200                 |
+---------------------+

審題
乍一看 這不就是把Salary排序然后用分頁查詢LIMIT把第二個取出來就可以了么庸推。
(但其實有幾個坑需要注意)

自己的解答

select Salary SecondHighestSalary
from employee
order by Salary DESC
limit 1,1;

沒有通過常侦,下面分析為什么沒有通過

解析

  1. 如果薪水是這樣的 1, 1, 1, 2, 2, ...
    上述代碼取出的依然是1 所以要利用DISTINCT去重 。

2.如果薪水只有一個呢 這樣上述代碼是有問題的
因此要排除這種情況

改進(jìn)

  • 利用IFNULL函數(shù) ifnull(x贬媒,y)聋亡,若x不為空則返回x,否則返回y
  • 利用子查詢
select ifnull(
    (select DISTINCT Salary 
    from employee
    order by Salary DESC
    limit 1,1), null
) as SecondHighestSalary;

這樣就通過了

再看看別的解法,比較一下快慢

其他解法
1.select null返回的是什么呢际乘? 返回的是NULL
可以利用這一點 將前述的代碼得到一個臨時表,再用select語句

select (
    select DISTINCT Salary 
    from employee
    order by Salary DESC
    limit 1,1
) as SecondHighestSalary;
  • limit n子句表示查詢結(jié)果返回前n條數(shù)據(jù)
    offset m表示跳過m條語句
    limit y offset x 分句表示查詢結(jié)果跳過 x 條數(shù)據(jù)杀捻,讀取前 y 條數(shù)據(jù)

2.也可以這樣做 先查出最大的salary 然后對小于最大的salary的salary去最大值不就是第二大了么

  • ①先取出最大的salary
select max(salary)
from employee;
  • ②取出小于①的最大的salary
select max(salary)  as SecondHighestSalary
from employee
where salary <(select max(salary)
                from employee);

3.(乍一看沒理解)利用偏序關(guān)系

  • 自己構(gòu)造數(shù)據(jù)方便實踐
CREATE DATABASE leetcode;

USE leetcode;
CREATE TABLE Employee (Id INT (10), Salary INT (10));
INSERT INTO Employee(Id, Salary) VALUE(1, 100), (2, 100), (3, 105), (4, 110), (5, 199);

SELECT *
FROM Employee;
  • 什么是偏序關(guān)系呢 好像離散數(shù)學(xué)學(xué)過的


SELECT l1.*, l2.*
FROM Employee l1 JOIN Employee l2 
WHERE l1.salary < l2.salary;

結(jié)果如下
  • 再找次序的最大值,就一定是第二高的薪水蚓庭。
  • max在沒有元組輸入時,還能返回NULL仅仆。

4.沒看懂的方法器赞。。

SELECT E1.`Salary`
FROM Employee AS E1
WHERE 1 = (
    SELECT COUNT(DISTINCT E2.`Salary`)
    FROM Employee AS E2
    WHERE E1.Salary < E2.Salary
);

先看一下這個代碼

SELECT e1.`Salary`, COUNT(DISTINCT e2.salary)
FROM employee e1 JOIN employee e2 ON e1.salary <= e2.salary
GROUP BY e1.salary;

這個是干嘛呢墓拜,理解一下就是和上邊的方法三類似構(gòu)造偏序關(guān)系然后對e1.salary進(jìn)行分組再對e2.salary去重后統(tǒng)計數(shù)量港柜,得到的結(jié)果是什么呢?



其實得到的是Salary的排名。

其實很容易理解,構(gòu)造偏序關(guān)系得到的是("小Salary", "大Salary"),對"小Salary"進(jìn)行分組后對"大Salary"去重統(tǒng)計數(shù)量其實就是統(tǒng)計大于等于這個"小Salary"的數(shù)目夏醉。對于最大的值爽锥,數(shù)目顯然只有一個,因為只有一個(最大值,最大值), 對于第二大的值畔柔,數(shù)目顯然是兩個(第二大值氯夷,第二大值),(第二大值靶擦,最大值)腮考。

因此還可以這樣寫

SELECT DISTINCT e1.`Salary`
FROM employee e1 JOIN employee e2 ON e1.salary <= e2.salary
GROUP BY e1.salary
HAVING COUNT(DISTINCT e2.salary) = 2;

其實這里把2可以任意修改就得到任意排名的值。

再返回去看之前的代碼

SELECT E1.`Salary`
FROM Employee AS E1
WHERE 1 = (
    SELECT COUNT(DISTINCT E2.`Salary`)
    FROM Employee AS E2
    WHERE E1.Salary < E2.Salary
);

其實和后邊補充的思想是一致的玄捕,只不過分別是用子查詢和聯(lián)結(jié)來實現(xiàn)踩蔚,唯一的一點差別就是這里用了<而不是<=,因此這個代碼等于1即可枚粘,但其選不出最大值馅闽。

與下面的代碼是等價的

SELECT E1.`Salary` AS SecondHighestSalary
FROM Employee AS E1
WHERE 2 = (
    SELECT COUNT(DISTINCT E2.`Salary`)
    FROM Employee AS E2
    WHERE E1.Salary <= E2.Salary
);

提交了一下,居然還是報錯馍迄。其實還是NULL的問題福也,可以在最開始取MAX(),也可以利用IFNULL函數(shù)柬姚。

SELECT MAX(E1.`Salary`) AS SecondHighestSalary
FROM Employee AS E1
WHERE 2 = (
    SELECT COUNT(DISTINCT E2.`Salary`)
    FROM Employee AS E2
    WHERE E1.Salary <= E2.Salary
);

5.利用窗口函數(shù)
這個好像是mysql8.0以上有的特性
挖個坑吧

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拟杉,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子量承,更是在濱河造成了極大的恐慌搬设,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撕捍,死亡現(xiàn)場離奇詭異拿穴,居然都是意外死亡,警方通過查閱死者的電腦和手機忧风,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進(jìn)店門默色,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人狮腿,你說我怎么就攤上這事腿宰。” “怎么了缘厢?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵吃度,是天一觀的道長。 經(jīng)常有香客問我贴硫,道長椿每,這世上最難降的妖魔是什么伊者? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮间护,結(jié)果婚禮上亦渗,老公的妹妹穿的比我還像新娘。我一直安慰自己汁尺,他們只是感情好法精,可當(dāng)我...
    茶點故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著均函,像睡著了一般亿虽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上苞也,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天洛勉,我揣著相機與錄音,去河邊找鬼如迟。 笑死收毫,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的殷勘。 我是一名探鬼主播此再,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼玲销!你這毒婦竟也來了输拇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤贤斜,失蹤者是張志新(化名)和其女友劉穎策吠,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瘩绒,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡猴抹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了锁荔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蟀给。...
    茶點故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖阳堕,靈堂內(nèi)的尸體忽然破棺而出跋理,到底是詐尸還是另有隱情,我是刑警寧澤恬总,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布前普,位于F島的核電站,受9級特大地震影響越驻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一缀旁、第九天 我趴在偏房一處隱蔽的房頂上張望记劈。 院中可真熱鬧,春花似錦并巍、人聲如沸目木。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽刽射。三九已至,卻和暖如春剃执,著一層夾襖步出監(jiān)牢的瞬間誓禁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工肾档, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留摹恰,地道東北人。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓怒见,卻偏偏與公主長得像俗慈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子遣耍,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,969評論 2 355