目錄
1.樹節點(608)
示例 1
解法一(case when)
解法二(not in)
2.判斷三角形(610)
示例 1
解法一(case when)
解法二(if)
解法三(嵌套if)
3.只出現一次的最大數字(619)
示例 1
解法一(count limit)
解法二(max)
4.有趣的電影(620)
解法一
5.換座位(626)
示例 1
解法一(case when)
解法二(count mod case-when)
解法三(union)
解法四(Lag/Lead)
6.變更性別(627)
示例 1
解法一(case when)
解法二(if)
7.買下所以產品的客戶(1045)
示例 1
解法一(count)
解法二(嵌套select)
1.樹節點(608)
表:Tree
+-------------+------+ | Column Name | Type | +-------------+------+ | id | int | | p_id | int | +-------------+------+ id 是該表中具有唯一值的列。 該表的每行包含樹中節點的 id 及其父節點的 id 信息。 給定的結構總是一個有效的樹。
樹中的每個節點可以是以下三種類型之一:
- "Leaf":節點是葉子節點。
- "Root":節點是樹的根節點。
- "lnner":節點既不是葉子節點也不是根節點。
編寫一個解決方案來報告樹中每個節點的類型。
以?任意順序?返回結果表。
結果格式如下所示。
示例 1
輸入: Tree table: +----+------+ | id | p_id | +----+------+ | 1 | null | | 2 | 1 | | 3 | 1 | | 4 | 2 | | 5 | 2 | +----+------+ 輸出: +----+-------+ | id | type | +----+-------+ | 1 | Root | | 2 | Inner | | 3 | Leaf | | 4 | Leaf | | 5 | Leaf | +----+-------+ 解釋: 節點 1 是根節點,因為它的父節點為空,并且它有子節點 2 和 3。 節點 2 是一個內部節點,因為它有父節點 1 和子節點 4 和 5。 節點 3、4 和 5 是葉子節點,因為它們有父節點而沒有子節點。
解法一(case when)
首先根節點很好判斷,先用一個flag 區分出根和非根,然后用p_id是否含有id,根據這個標準判斷是否葉節點.
# Write your MySQL query statement below
select id,case
when flag=0 then 'Root'
when p_id is not null then 'Inner'
else 'Leaf'
end as type
from (select id,if((p_id is null),0,1) flag from tree ) a
left join
(select p_id from tree where p_id is not null group by p_id) b
on a.id=b.p_id
解法二(not in)
用case when,先判斷是否根節點,然后根據一個內查詢再區分是否葉節點,這個方法雖然簡單點,但not in 較為損耗性能,總體速度與解法一差不多.
SELECTid,(CASEWHEN p_id IS NULL THEN 'Root'WHEN id NOT IN(SELECTp_idFROM treeWHERE p_id IS NOT NULL) THEN 'Leaf'ELSE 'Inner'END)as type
FROM tree
2.判斷三角形(610)
表:?Triangle
+-------------+------+ | Column Name | Type | +-------------+------+ | x | int | | y | int | | z | int | +-------------+------+ 在 SQL 中,(x, y, z)是該表的主鍵列。 該表的每一行包含三個線段的長度。
對每三個線段報告它們是否可以形成一個三角形。
以?任意順序?返回結果表。
查詢結果格式如下所示。
示例 1
輸入: Triangle 表: +----+----+----+ | x | y | z | +----+----+----+ | 13 | 15 | 30 | | 10 | 20 | 15 | +----+----+----+ 輸出: +----+----+----+----------+ | x | y | z | triangle | +----+----+----+----------+ | 13 | 15 | 30 | No | | 10 | 20 | 15 | Yes | +----+----+----+----------+
解法一(case when)
利用三角形兩邊之和大于第三邊性質.
# Write your MySQL query statement below
select *,
case when (x+y)>z and (x+z)>y and (y+z)>x then 'Yes'
else 'No'
end as triangle
from triangle
解法二(if)
Select *,IF(x+y>z and x+z>y and y+z>x, "Yes", "No") AS triangle
FROM triangle
解法三(嵌套if)
這個是力扣上的友友寫的,他的速度是最快的.
原理:x + y + z > 2 * max(x, y, z) [x + y + z > z + z, 三條件組合]
select x, y, z,
if(x + y + z > 2 * if(x > y and x > z, x, if(y > x and y > z, y, z)), 'Yes', 'No') triangle
from Triangle
3.只出現一次的最大數字(619)
MyNumbers
?表:
+-------------+------+ | Column Name | Type | +-------------+------+ | num | int | +-------------+------+ 該表可能包含重復項(換句話說,在SQL中,該表沒有主鍵)。 這張表的每一行都含有一個整數。
單一數字?是在?MyNumbers
?表中只出現一次的數字。
找出最大的?單一數字?。如果不存在?單一數字?,則返回?null
?。
查詢結果如下例所示。
示例 1
輸入: MyNumbers 表: +-----+ | num | +-----+ | 8 | | 8 | | 3 | | 3 | | 1 | | 4 | | 5 | | 6 | +-----+ 輸出: +-----+ | num | +-----+ | 6 | +-----+ 解釋:單一數字有 1、4、5 和 6 。 6 是最大的單一數字,返回 6 。
解法一(count limit)
首先根據count()選出只出現一次的數,然后排序加分頁選出最大一個.
# Write your MySQL query statement below
select
case
when count(*)=1 then num
when num is null then null
end as 'num' from MyNumbers group by num order by num desc limit 1
解法二(max)
因為本題出現了null.所以我們需要null的數據,下面是從網上找的一些總結,發現,原來一些聚合函數自帶null.本方法較快
# Write your MySQL query statement below
# 表格為空,加入任何SUM/AVG/MAX/MIN函數,都可以得到null值的結果。
# 可以使用聚合函數進行空值null值的轉換,具體的聚合函數包括SUM/AVG/MAX/MIN
# 可以使用select語句進行轉換,但空值應直接寫在select中而非from中
# limit語句無法出現新的null值
# where和having同樣無法出現新的null值# ifnull函數定位:用于判斷第一個表達式是否為 NULL,如果為 NULL 則返回第二個參數的值,如果不為 NULL 則返回第一個參數的值。
# IFNULL(expression, alt_value)SELECTMAX(num) AS num
FROM(SELECTnumFROMMyNumbersGROUP BY numHAVING COUNT(num) = 1) AS t
;
4.有趣的電影(620)
某城市開了一家新的電影院,吸引了很多人過來看電影。該電影院特別注意用戶體驗,專門有個 LED顯示板做電影推薦,上面公布著影評和相關電影描述。
作為該電影院的信息部主管,您需要編寫一個 SQL查詢,找出所有影片描述為非?boring
?(不無聊)?的并且?id 為奇數?的影片,結果請按等級?rating
?排列。
例如,下表?cinema
:
+---------+-----------+--------------+-----------+ | id | movie | description | rating | +---------+-----------+--------------+-----------+ | 1 | War | great 3D | 8.9 | | 2 | Science | fiction | 8.5 | | 3 | irish | boring | 6.2 | | 4 | Ice song | Fantacy | 8.6 | | 5 | House card| Interesting| 9.1 | +---------+-----------+--------------+-----------+
對于上面的例子,則正確的輸出是為:
+---------+-----------+--------------+-----------+ | id | movie | description | rating | +---------+-----------+--------------+-----------+ | 5 | House card| Interesting| 9.1 | | 1 | War | great 3D | 8.9 | +---------+-----------+--------------+-----------+
解法一
# Write your MySQL query statement below
select * from cinema where description !='boring' and id%2=1 order by rating desc
5.換座位(626)
表:?Seat
+-------------+---------+ | Column Name | Type | +-------------+---------+ | id | int | | name | varchar | +-------------+---------+ id是該表的主鍵(唯一值)列。 該表的每一行都表示學生的姓名和 ID。 id 是一個連續的增量。
編寫解決方案來交換每兩個連續的學生的座位號。如果學生的數量是奇數,則最后一個學生的id不交換。
按?id
?升序?返回結果表。
查詢結果格式如下所示。
示例 1
輸入: Seat 表: +----+---------+ | id | student | +----+---------+ | 1 | Abbot | | 2 | Doris | | 3 | Emerson | | 4 | Green | | 5 | Jeames | +----+---------+ 輸出: +----+---------+ | id | student | +----+---------+ | 1 | Doris | | 2 | Abbot | | 3 | Green | | 4 | Emerson | | 5 | Jeames | +----+---------+ 解釋: 請注意,如果學生人數為奇數,則不需要更換最后一名學生的座位。
解法一(case when)
用左連接將三個表連接起來,然后用case when判斷是否空就行.這個是修改名字
select a.id,case when b.student is not null then b.student
when c.student is not null then c.student
else a.student
end as 'student' from seat a left join seat b on a.id=b.id-1 and a.id%2=1
left join seat c on a.id=c.id+1 and a.id%2=0
解法二(count mod case-when)
用count區分總數是單還是雙,然后用case判斷id,這個是變相修改id
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,(SELECTCOUNT(*) AS countsFROMseat) AS seat_counts
ORDER BY id ASC;
解法三(union)
使用left join和union實現 先改奇數id學生的名字,再改偶數id學生的名字,全改過來后,
再union合并所有的id
select a.id as id,ifnull(b.student,a.student) as student from Seat as a
left join (select * from Seatwhere mod(id,2) = 0
) as b
on (a.id+1) = b.id
where mod(a.id,2) = 1
union
select c.id as id,d.student as student from Seat as c
left join (select * from Seatwhere mod(id,2) = 1
) as d
on (c.id-1) = d.id
where mod(c.id,2) = 0
order by id asc;
解法四(Lag/Lead)
Lag/Lead(col,n,DEFAULT) 用于統計窗口內當前行往前或者往后第n行值
- 第一個參數為列名,
- 第二個參數為往后/前第n行(可選,默認為1),
- 第三個參數為默認值(當往上第n行為NULL時候,取默認值,如不指定,則為NULL)
需要注意的是lag 取得是當前行之前的數據,lead 取的實當前行之后的數據
SELECT id,IF(id % 2 = 0, last, next) student
FROM (SELECT id,student,lag(student,1,student) over(order by id) last,lead(student,1,student) over(order by id) nextFROM seat
) t;
6.變更性別(627)
Salary
?表:
+-------------+----------+ | Column Name | Type | +-------------+----------+ | id | int | | name | varchar | | sex | ENUM | | salary | int | +-------------+----------+ id 是這個表的主鍵。 sex 這一列的值是 ENUM 類型,只能從 ('m', 'f') 中取。 本表包含公司雇員的信息。
請你編寫一個 SQL 查詢來交換所有的?'f'
?和?'m'
?(即,將所有?'f'
?變為?'m'
?,反之亦然),僅使用?單個 update 語句?,且不產生中間臨時表。
注意,你必須僅使用一條 update 語句,且?不能?使用 select 語句。
查詢結果如下例所示。
示例 1
輸入: Salary 表: +----+------+-----+--------+ | id | name | sex | salary | +----+------+-----+--------+ | 1 | A | m | 2500 | | 2 | B | f | 1500 | | 3 | C | m | 5500 | | 4 | D | f | 500 | +----+------+-----+--------+ 輸出: +----+------+-----+--------+ | id | name | sex | salary | +----+------+-----+--------+ | 1 | A | f | 2500 | | 2 | B | m | 1500 | | 3 | C | f | 5500 | | 4 | D | m | 500 | +----+------+-----+--------+ 解釋: (1, A) 和 (3, C) 從 'm' 變為 'f' 。 (2, B) 和 (4, D) 從 'f' 變為 'm' 。
解法一(case when)
# Write your MySQL query statement below
update salary set sex=(case when sex='m' then 'f'else 'm'end
)
解法二(if)
# Write your MySQL query statement below
update salary set sex=(if(sex='m','f','m'))
解法三(replace)
最快
# replace(‘總字符串’,要下場的字符,要上場的字符)
update salary set sex = replace("fm", sex, "")
7.買下所以產品的客戶(1045)
Customer
?表:
+-------------+---------+ | Column Name | Type | +-------------+---------+ | customer_id | int | | product_key | int | +-------------+---------+ 該表可能包含重復的行。 customer_id 不為 NULL。 product_key 是 Product 表的外鍵(reference 列)。
Product
?表:
+-------------+---------+ | Column Name | Type | +-------------+---------+ | product_key | int | +-------------+---------+ product_key 是這張表的主鍵(具有唯一值的列)。
編寫解決方案,報告?Customer
?表中購買了?Product
?表中所有產品的客戶的 id。
返回結果表?無順序要求?。
返回結果格式如下所示。
示例 1
輸入: Customer 表: +-------------+-------------+ | customer_id | product_key | +-------------+-------------+ | 1 | 5 | | 2 | 6 | | 3 | 5 | | 3 | 6 | | 1 | 6 | +-------------+-------------+ Product 表: +-------------+ | product_key | +-------------+ | 5 | | 6 | +-------------+ 輸出: +-------------+ | customer_id | +-------------+ | 1 | | 3 | +-------------+ 解釋: 購買了所有產品(5 和 6)的客戶的 id 是 1 和 3 。
解法一(count)
根據數量判斷
# Write your MySQL query statement below
select customer_id from customer group by customer_id
having count(distinct product_key)=(select count(*) from product)
解法二(嵌套select)
SELECT customer_id, product_key?
FROM Customer GROUP BY customer_id, product_key
這段用來去重,然后從這里再分組count,最后根據產品數量比較
# Write your MySQL query statement below
SELECT customer_id
FROM (SELECT customer_id, COUNT(*) AS 'number'
FROM (SELECT customer_id, product_key
FROM Customer GROUP BY customer_id, product_key) a
GROUP BY customer_id) b
WHERE number = (SELECT COUNT(DISTINCT product_key) FROM Product);