HelloU跋搿鼻吮!我回歸啦~ 今天開始繼續(xù)刷SQL的題目~ 爭取這個寒假可以在SQL有一點點進步垂攘!
闖關(guān)開始啦
關(guān)卡1 -?組合兩個表
思路:
這道題說不管person是否有信息都應(yīng)該被merge揭保。所以我們應(yīng)該把有person的那張表作為主表谆棺,然后把另一張表left join進來疚沐,這樣就可以確保person都存在暂氯。
那是不是這樣就好了呢?
SELECT?FirstName,LastName FROM?Person
LEFT?JOIN??Address
ON?Person.PersonId?=?Address.PersonId
錯亮蛔!這里痴施,兔子還遇到一個問題,就是我們并沒有提供city和state
但是city 和 state 明明是在另外的一個表格究流,怎么才能讓他也被選擇進來呢辣吃?我們可以在第一行就輸入這兩個來自另一個表格的變量。
SELECT?FirstName,LastName,City,State FROM?Person
LEFT?JOIN??Address
ON?Person.PersonId?=?Address.PersonId
這樣就運行成功啦芬探!However神得,為了讓他更加直觀,我們一般會在第一行的這些變量前面加上一個表格的首字母.
所以就是:
SELECT P.FirstName, P.LastName, A.City, A.State? FROM?Person P
LEFT?JOIN??Address A
ON?P.PersonId?=?A.PersonId
恭喜過關(guān)偷仿!進入下一關(guān)哩簿!
關(guān)卡2 -?第二高的薪水
思路:
這道題看起來好像挺簡單的宵蕉!
他想要生成一個新的列,我們就用AS關(guān)鍵字节榜,想要排序羡玛,我們就進行ORDER BY,想要從大到小宗苍,我們就descending order用DESC缝左,想只生成第二個,我們就LIMIT 1 OFFSET 1浓若,這些語法在我之前的文章都介紹過了~
所以我刷刷刷寫下來如下代碼
SELECT DISTINCT Salary AS SecondHighestSalary?
FROM Employee
ORDER BY SecondHighestSalary DESC
LIMIT 1 OFFSET 1
但是!提交之后顯示錯誤了蛇数。
那么問題出在哪里呢~問題就是挪钓,當(dāng)不存在第二高的薪水時,系統(tǒng)并沒有返回NULL
所以我們要把我們之前的代碼作為一個臨時表耳舅,我們要做一個表中表碌上,可以用到IFNULL語句,語法是:IFNULL((語句)浦徊,如果前面的語句是null的時候返回的東西)
那這里就是IFNULL((前面的代碼)馏予,NULL)
組合起來就是:
SELECT?IFNULL(
(SELECT?DISTINCT?Salary?
FROM?Employee
ORDER?BY?Salary?DESC
LIMIT?1?OFFSET?1),NULL)?AS?SecondHighestSalary
恭喜過關(guān)!進入下一關(guān)盔性!
關(guān)卡3 -?第N高的薪水
思路:
其實這道題和第二題很像霞丧,但是它是以一個N的形式出現(xiàn)
題目本身幫助我們定義了一個函數(shù)
CREATE?FUNCTION?getNthHighestSalary(N?INT)?RETURNS?INT
BEGIN
????RETURN?();
END
我們的任務(wù)就是在return里面寫代碼~
我的第一反應(yīng)是,那就復(fù)制之前的代碼冕香,然后把OFFSET 那里改成(N-1),然鵝??蛹尝,并沒有那么順利,我成功bug了
后來才知道悉尾,原來要在前面SET一個變量突那,讓這個變量等于N-1,然后再OFFSET這個變量
那么答案就是:
CREATE?FUNCTION?getNthHighestSalary(N?INT)?RETURNS?INT
BEGIN
????SET n =?N-1;
????RETURN?(
?????SELECT?IFNULL(
?????(SELECT?DISTINCT?Salary?
?????FROM?Employee
?????ORDER?BY?Salary?DESC
?????LIMIT?1?OFFSET n),NULL)?AS?SecondHighestSalary);
END
當(dāng)然构眯,也可以LIMIT n,1 而不要OFFSET愕难,但是意思是一樣的啦~LIMIT x,y ,是跳過x行,取y行數(shù)據(jù)的意思惫霸,類似于 limit y offset x
恭喜過關(guān)猫缭!進入下一關(guān)!
關(guān)卡4 -?分?jǐn)?shù)排名
思路:
這道題其實說實話壹店,兔子不懂饵骨。
哈哈哈哈哈哈哈~這么坑的嘛~~
所以呢,我就看了題解茫打,發(fā)現(xiàn)了我沒學(xué)過的東西~
那就是SQL的排名函數(shù)居触,也叫窗口函數(shù)妖混,解釋如下:
那這樣一來,這道題就變得很簡單啦轮洋,它需要我們用dense_rank() 函數(shù)來解決~
它的語法是直接在SELECT語句里面制市,在select之后,dense_rank()? over (你要進行的處理) AS ‘一個新的列名’ From 表格名
如下:
SELECT?Score,
dense_rank( )?over?(ORDER?BY?Score?DESC)?AS?'Rank'
From?Scores
恭喜過關(guān)弊予!進入下一關(guān)祥楣!
關(guān)卡5 -?連續(xù)出現(xiàn)的數(shù)字
思路:
自連接(自身連接),把一張表復(fù)制出多張一模一樣的表來使用汉柒。然后我們找出下面一行和上面一行误褪,如果這三個數(shù)字相等,說明他出現(xiàn)了三次碾褂。
那我們開始寫code兽间!
步驟1: 連接三表
SELECT?*?FROM?Logs?AS?a, Logs?AS?b, Logs?AS?c?
WHERE?a.Id?=?b.Id?+?1
AND?a.Id?=?c.Id?-?1
AND?a.NUM?=?b.NUM
AND?a.NUM?=?c.NUM
這時,最后兩行代碼限制了正塌,這三個數(shù)字必須相等才能留在這個表格
所以我們只需在SELECT語句加一個distinct嘀略,就能找出,重復(fù)三次的數(shù)字究竟是什么乓诽!
SELECT?DISTINCT?a.Num?AS?ConsecutiveNums?
FROM?Logs?AS?a,Logs?AS?b,Logs?AS?c
WHERE?a.Id?=?b.Id?+?1
AND?a.Id?=?c.Id?-?1
AND?a.Num?=?b.Num
AND?a.Num?=?c.Num
恭喜過關(guān)帜羊!
今天學(xué)到的新知識:SET,IFNULL 函數(shù)鸠天,limit X,Y = limit Y offset X, 窗口函數(shù)dense_rank()over(), rank()over(), row_number()over(), 自連接讼育。
明天繼續(xù)闖關(guān)~yay ~