175. 組合兩個表mysql
表1: Person
sql
+-------------+---------+ | 列名 | 類型 | +-------------+---------+ | PersonId | int | | FirstName | varchar | | LastName | varchar | +-------------+---------+ PersonId 是上表主鍵
表2: Address
函數
+-------------+---------+ | 列名 | 類型 | +-------------+---------+ | AddressId | int | | PersonId | int | | City | varchar | | State | varchar | +-------------+---------+ AddressId 是上表主鍵
編寫一個 SQL 查詢,知足條件:不管 person 是否有地址信息,都須要基於上述兩表提供 person 的如下信息: spa
FirstName, LastName, City, State
比較簡單,使用左鏈接便可實現。左鏈接就是保證左邊記錄必定有,右鏈接就是保證右邊記錄必定有。另外注意語法是select * from 表1 left join 表2 on 表1.列名=表2.列名.net
提交答案:調試
select Person.FirstName, Person.LastName, Address.City, Address.State from Person left join Address on Person.PersonId=Address.PersonId;code
176. 第二高的薪水blog
編寫一個 SQL 查詢,獲取 Employee
表中第二高的薪水(Salary) 。排序
+----+--------+ | Id | Salary | +----+--------+ | 1 | 100 | | 2 | 200 | | 3 | 300 | +----+--------+
例如上述 Employee
表,SQL查詢應該返回 200
做爲第二高的薪水。若是不存在第二高的薪水,那麼查詢應返回 null
。ip
+---------------------+ | SecondHighestSalary | +---------------------+ | 200 | +---------------------+
這道題原本覺得很簡單,結果在對null的處理上費了很大勁,最後仍是去網上找的別人的答案。如下引用自https://blog.csdn.net/havedream_one/article/details/45394127:
一、去重,因此使用group by進行分組
二、因爲要獲得第二大工資,因此須要進行排序,
三、max獲得的最大值,可是要獲得第二個最大值,因此要使用limit 1,1
limit start,len
start 表示頁數,0,1,2,3....
len表示頁的記錄數
四、因爲答案的列名是SecondHighestSalary,因此最後要使用as 重命名
五、須要使用兩個select,第二個select用於重建列和列值。由於second highest salary 若是不存在的話,那麼內部的select返回值是null,不符合答案。所以須要對內部select進行重建列和列值。
第五點須要兩個select,經過mysql作實驗確實如此,若是隻有一層select,返回null,對其count返回0;兩個select會返回一條null的記錄,對其count返回1。具體緣由還不清楚。
提交答案1(967ms):
SELECT MAX(Salary) as SecondHighestSalary
FROM Employee
WHERE Salary < (SELECT MAX(Salary) FROM Employee);
提交答案2(511ms):
select(select salary from Employee group by salary order by salary desc limit 1,1) as 'SecondHighestSalary';
177. 第N高的薪水
編寫一個 SQL 查詢,獲取 Employee
表中第 n 高的薪水(Salary)。
+----+--------+ | Id | Salary | +----+--------+ | 1 | 100 | | 2 | 200 | | 3 | 300 | +----+--------+
例如上述 Employee
表,n = 2 時,應返回第二高的薪水 200
。若是不存在第 n 高的薪水,那麼查詢應返回 null
。
+------------------------+ | getNthHighestSalary(2) | +------------------------+ | 200 | +------------------------+
若是直接來這道題可能以爲很難,不過在第二高薪水以後,只須要改limit後面的條件就能夠了。這裏使用了函數輸入N,mysql的自定義函數以前沒有用過。注意到Limit並不支持N-1這種計算,只能直接輸入相似1,2,N這種數字。在Select上一行寫N=N-1結果語法錯誤,其實應該寫在Return的外面,即Begin下面加上
SET N = N - 1;
提交答案:
CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
SET N = N - 1;
RETURN (
# Write your MySQL query statement below.
SELECT ( SELECT salary FROM Employee GROUP BY salary ORDER BY salary DESC LIMIT N, 1 ) AS 'SecondHighestSalary'
);
END
178. 分數排名
編寫一個 SQL 查詢來實現分數排名。若是兩個分數相同,則兩個分數排名(Rank)相同。請注意,平分後的下一個名次應該是下一個連續的整數值。換句話說,名次之間不該該有「間隔」。
+----+-------+ | Id | Score | +----+-------+ | 1 | 3.50 | | 2 | 3.65 | | 3 | 4.00 | | 4 | 3.85 | | 5 | 4.00 | | 6 | 3.65 | +----+-------+
例如,根據上述給定的 Scores
表,你的查詢應該返回(按分數從高到低排列):
+-------+------+ | Score | Rank | +-------+------+ | 4.00 | 1 | | 4.00 | 1 | | 3.85 | 2 | | 3.65 | 3 | | 3.65 | 3 | | 3.50 | 4 | +-------+------+
名次實際上就是統計有幾我的比我高,名次之間沒有間隔就是須要去重。
提交答案:
select t.Score, (select count(distinct Score) from Scores where Score >= t.Score) as Rank from Scores t order by Score desc;
另外提一句,在調試語句的時候碰到了一個錯誤,err:1248 - Every derived table must have its own alias。這個錯誤的意思是說每一個派生出來的表都必須有一個本身的別名。例如:
個人Mysql語句是:select count(*) from (select * from dede_spacemoney group by sid) ;
當我執行到這裏的時候就拋出了這個異常,原來我進行嵌套查詢的時候子查詢出來的的結果是做爲一個派生表來進行上一級的查詢的,因此子查詢的結果必需要有一個別名
把MySQL語句改爲:select count(*) from (select * from list where name="xiao") as t;
問題就解決了。參考http://www.javashuo.com/article/p-ueeksbly-no.html。