知識點: ① ord():返回字符對應的ASCII數值(或Unicode數值),是chr()函數(對于8位的ASCII字符串)或unichr()函數(對于Unicode對象)的配對函數 ② bin():返回一個整數int或者長整數long int的二進制表示 ③ 按位異或運算符(^):當兩對應的二進位相異時,結果為1
UPDATE salary
SET sex = CHAR(ASCII('f') ^ ASCII('m') ^ ASCII(sex));
2. 查詢當天氣溫比前一天氣溫高的日期。
題目詳情
解題方法1
知識點: ① DATEDIFF(date1, date2):返回兩個日期之間的天數
SELECT w1.Id
FROM Weather w1
INNER JOIN Weather w2 ON DATEDIFF(w1.RecordDate, w2.RecordDate) = 1
AND w1.Temperature > w2.Temperature;
解題方法2
知識點: ① 窗口函數中的前后函數LAG(expr, 1):返回位于當前行的前n行的expr的值 但這個方法在LeetCode中沒法通過,總報語法錯誤,不解。
mysql> SELECT Id-> FROM (-> SELECT *,-> LAG(Temperature, 1) OVER w AS pre_Temperature-> FROM Weather-> WINDOW w AS (ORDER BY Id)) a-> WHERE Temperature > pre_Temperature;
+------+
| Id |
+------+
| 2 |
| 4 |
+------+
3. 刪除重復的郵件信息。
題目詳情
解題方法1
知識點: ① 刪除操作:DELETE FROM tb_name WHERE... ② MIN()函數
DELETE
FROM Person
WHERE id NOT IN (SELECT id_emailFROM (SELECT email, MIN(id) id_emailFROM PersonGROUP BY email)t1);
解題方法2
這個方法沒有使用DELETE,不滿足題目的要求。
mysql> SELECT id, email-> FROM (-> SELECT *, ROW_NUMBER() OVER (PARTITION BY email ORDER BY id) 'col_3'-> FROM tb_196)t-> WHERE col_3 = 1-> ORDER BY id;
+------+------------------+
| id | email |
+------+------------------+
| 1 | john@example.com |
| 2 | bob@example.com |
+------+------------------+
4. 檢索第二高薪。
題目詳情
解題方法1
知識點: ① DISTINCT關鍵字 ② 臨時表:若表中只有一個記錄,則不存在第二高薪。為了解決NULL問題,可以使用臨時表
SELECT (SELECT DISTINCT SalaryFROM EmployeeORDER BY Salary DESCLIMIT 1,1) AS SecondHighestSalary;
解題方法2
知識點: ① IFNULL(expr1,expr2):如果expr1不是NULL,返回expr1;否則返回expr2 這題可以使用IFNULL()解決NULL問題。
SELECT
IFNULL((SELECT DISTINCT SalaryFROM EmployeeORDER BY Salary DESCLIMIT 1 OFFSET 1),NULL) AS SecondHighestSalary;
測試語句
mysql> SELECT * FROM test;
+--------+
| salary |
+--------+
| 100 |
| 100 |
+--------+情況1:不使用DISTINCT關鍵字,不符合條件
mysql> SELECT salary-> FROM test-> ORDER BY salary-> LIMIT 1,1;
+--------+
| salary |
+--------+
| 100 |
+--------+
1 row in set (0.00 sec)情況2:使用DISTINCT關鍵字,符合條件
mysql> SELECT DISTINCT salary-> FROM test-> ORDER BY salary-> LIMIT 1,1;
Empty set (0.00 sec)
5. 交換相鄰座位的座位號。
題目詳情
解題方法
知識點: ① MOD(n1,n2):返回余數 ② CASE WHEN ...THEN... ELSE... END 思路: 情況1:奇數id & 非末尾id —> id+1 情況2:奇數id & 末尾id —> id不變 情況3:偶數id —> id-1
SELECT(CASEWHEN MOD(id, 2) != 0 AND counts != id THEN id + 1WHEN MOD(id, 2) != 0 AND counts = id THEN idELSE id - 1END) AS id,student
FROMseat,(SELECT COUNT(*) AS counts FROM seat) AS seat_counts
ORDER BY id;
6. 檢索連續出現3次的數字。
題目詳情
解題方法
知識點: ① 自聯結;②DISTINCT關鍵字 思路: 連續出現意味著Num的Id與彼此相鄰。由于此問題要求數字連續出現至少三次,我們可以為此表Logs使用3個別名,然后檢查3個連續數字是否全部相同。
SELECT DISTINCT t1.num AS ConsecutiveNums
FROM Logs t1, Logs t2, Logs t3
WHERE t1.id = t2.id-1 AND t2.id = t3.id-1
AND t1.num = t2.num AND t2.num = t3.num;
測試語句
mysql> SELECT * FROM tb_180;
+------+------+
| id | num |
+------+------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 1 |
| 6 | 2 |
| 7 | 2 |
| 8 | 2 |
| 8 | 2 |
+------+------+情況1:不使用DISTINCT關鍵字,不符合條件
mysql> SELECT t1.num-> FROM tb_180 t1, tb_180 t2, tb_180 t3-> WHERE t1.id = t2.id-1 AND t2.id = t3.id-1-> AND t1.num = t2.num AND t2.num = t3.num;
+------+
| num |
+------+
| 1 |
| 2 |
| 2 |
+------+情況1:使用DISTINCT關鍵字,符合條件
mysql> SELECT DISTINCT t1.num-> FROM tb_180 t1, tb_180 t2, tb_180 t3-> WHERE t1.id = t2.id-1 AND t2.id = t3.id-1-> AND t1.num = t2.num AND t2.num = t3.num;
+------+
| num |
+------+
| 1 |
| 2 |
+------+
7. 檢索部門最高薪水。
題目詳情
解題方法1
知識點: ① 內聯結; ② WHERE子句:WHERE (col1, col2) IN (SELECT col1, col2 FROM ...)
SELECT t2.name AS 'Department', t1.name AS 'Employee', salary
FROM Employee t1
INNER JOIN Department t2 ON t1.departmentid = t2.id
WHERE (t1.departmentid, salary) IN(SELECT departmentid, MAX(salary)FROM EmployeeGROUP BY departmentid);
解題方法2
知識點: 窗口函數:序號函數(ROW_NUMBER())
mysql> SELECT t2.name AS Department, t1.name AS Employee, salary-> FROM-> (SELECT *, ROW_NUMBER() OVER (PARTITION BY departmentid ORDER BY salary DESC) AS 'salary_order' FROM tb_1841)t1,-> tb_1842 t2-> WHERE departmentid = t2.id AND t1.salary_order = 1;
+------------+----------+--------+
| Department | Employee | salary |
+------------+----------+--------+
| IT | Max | 90000 |
| Sales | Henry | 80000 |
+------------+----------+--------+
8. 檢索第N高薪(創建自定義函數)。
題目詳情
解題方法
知識點: ① 創建自定義函數: CREATE FUNCTION func_name(參數 參數類型) RETURNS 返回值類型 BEGIN... END
CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGINSET N = N-1;RETURN (SELECT Salary FROM EmployeeGROUP BY SalaryORDER BY Salary DESCLIMIT N, 1);
END
9. 檢索最少連續3天超過100人參觀體育館的信息。
題目詳情
解題方法
思路: ① 笛卡爾積:檢索出6x6x6條信息 ② 假設t1的檢索列分別位于三天中的第1天、第2天、第3天,其中t2、t3的順序保持不變: 情況1:t1 ->t2 ->t3 情況2:t2 ->t1 ->t3 情況3:t2 ->t3 ->t1
SELECT DISTINCT t1.*
FROM stadium t1, stadium t2, stadium t3
WHERE t1.people >= 100 AND t2.people >= 100 AND t3.people >= 100
AND ((t3.id-t2.id = 1 AND t3.id-t1.id = 2 AND t2.id-t1.id = 1)OR(t3.id-t1.id = 1 AND t3.id-t2.id = 2 AND t1.id-t2.id = 1)OR(t1.id-t3.id = 1 AND t1.id-t2.id = 2 AND t3.id-t2.id = 1)
)
ORDER BY id;
10. 檢索每個部門的前3高薪。
題目詳情
解題方法1
思路: 前3高薪,則說明同部門比當前高薪高的人數少于3,使用自聯結。
SELECT a.name AS 'Department', Employee, Salary
FROM Department a
INNER JOIN (SELECT t1.name AS 'Employee', t1.Salary, t1.departmentidFROM Employee t1WHERE 3 > (SELECT COUNT(DISTINCT t2.Salary)FROM Employee t2WHERE t2.Salary > t1.Salary AND t1.departmentid = t2.departmentid))b
ON departmentid = id
ORDER BY Department, Salary DESC;
解題方法2
知識點: 窗口函數:序號函數(DENSE_RANK())
mysql> SELECT Department, Employee, Salary-> FROM (-> SELECT t2.name AS 'Department', t1.name AS 'Employee', salary, DENSE_RANK() OVER (PARTITION BY departmentid ORDER BY salary DESC) AS 'salary_order'-> FROM tb_1851 t1-> INNER JOIN tb_1852 t2 ON departmentid = t2.id) a-> WHERE salary_order IN (1,2,3);
+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT | Max | 90000 |
| IT | Randy | 85000 |
| IT | Joe | 70000 |
| Sales | Henry | 80000 |
| Sales | Sam | 60000 |
+------------+----------+--------+
SELECT request_at AS 'Day',(CASEWHEN request_at = '2013-10-01'THEN ROUND(SUM(CASE WHEN banned = 'No' AND status != 'completed' THEN 1 ELSE 0 END) / SUM(CASE WHEN banned = 'No' THEN 1 ELSE 0 END), 2)WHEN request_at = '2013-10-02'THEN ROUND(SUM(CASE WHEN banned = 'No' AND status != 'completed' THEN 1 ELSE 0 END) / SUM(CASE WHEN banned = 'No' THEN 1 ELSE 0 END), 2)WHEN request_at = '2013-10-03'THEN ROUND(SUM(CASE WHEN banned = 'No' AND status != 'completed' THEN 1 ELSE 0 END) / SUM(CASE WHEN banned = 'No' THEN 1 ELSE 0 END), 2)END) AS 'Cancellation Rate'
FROM (SELECT client_id, banned, status, request_atFROM Trips aINNER JOIN Users b ON client_id = users_idWHERE request_at IN ('2013-10-01','2013-10-02','2013-10-03')) t
GROUP BY request_at
;