編寫 SQL 查詢獲取 Employee 表中第二高的薪資。若不存在第二高薪資(如所有薪資相同或僅有一條記錄),查詢應返回 NULL。
CREATE TABLE Employee (
Id INT PRIMARY KEY,
Salary INT
);
SELECT MAX(Salary) FROM EmployeeSELECT MAX(Salary) FROM Employee WHERE Salary < (最高薪資)MAX() 返回 NULL
SELECT MAX(Salary) AS SecondHighestSalary
FROM Employee
WHERE Salary < (SELECT MAX(Salary) FROM Employee);
| 寫法 | SQL | 優缺點 |
|---|---|---|
| 子查詢(推薦) | 見上 | 簡潔、標準 SQL、自動處理 NULL |
| LIMIT/OFFSET | SELECT DISTINCT Salary FROM Employee ORDER BY Salary DESC LIMIT 1 OFFSET 1 | MySQL/PostgreSQL 專用、需包裝子查詢處理 NULL |
| 窗口函數(8.0+) | SELECT DISTINCT Salary FROM (SELECT Salary, DENSE_RANK() OVER (ORDER BY Salary DESC) AS rk FROM Employee) t WHERE rk = 2 | 通用性強、擴展性好、語法較複雜 |
| 自連接 | SELECT MAX(e1.Salary) FROM Employee e1 JOIN Employee e2 ON e1.Salary < e2.Salary | 直觀但效能較差、產生笛卡爾積 |
-- 測試數據 1:正常情況
INSERT INTO Employee VALUES (1, 100), (2, 200), (3, 300);
-- 結果:200
-- 測試數據 2:重複最高薪資
INSERT INTO Employee VALUES (1, 100), (2, 200), (3, 200);
-- 結果:100(第二高不同值)
-- 測試數據 3:單行/全同
INSERT INTO Employee VALUES (1, 100);
-- 結果:NULL
Salary 列有索引可進一步優化ORDER BY ... LIMIT 在大表上無索引時的 filesortPARTITION BY DepartmentId)