週一傍晚跑步,王城大道的天橋上,偶遇一個高三的小姑娘在那兒拿着卷子站在天橋上的角落裏不知道背些什麼,頓時心裏一陣翻湧。或許在許多城市的許多隱蔽的角落,都藏着一個個小小的夢想。年輕人們,好好學吧,無論做什麼,今天在家多學一門技術,明天出去少一句求人的話。
數據庫專題
簡單
595. 大的國家
題目鏈接: 點擊傳送至本題
題目大意:
有World表(name,continent ,area,population,gdp)
,關於大國的定義是面積超過300萬平方公里或人口超過2500萬。現在要求查出其中大國的(name,population,area)信息。
解題思路:
方法1:
此題較容易,可以在where限定語句後配合or來完成兩個篩選條件的連接。
方法2:(優)
此題雖容易,但爲了提高效率可以使用union替代or。在這裏union的效率會比or的速度更快。
# 595. 大的國家
# 方法1:
select name,population,area
from World
where area>3000000 or population>25000000;
# 方法2(優)
select name,population,area
from World
where area>3000000
union
select name,population,area
from World
where population>25000000;
596. 超過5名學生的課
題目鏈接: 點擊傳送至本題
題目大意:
有courses表(student,class),要求查詢出選課人數大於等於5的課程。
解題思路:
方法1:
提取出一個包含課程字段、每個課程的選課人數的字段 的臨時表,然後在此臨時表上添加where篩選條件。需要注意的是每個課程的選課人數使用count(student)配合group by class
來完成,由於此題測試用例中包含重複數據,如學生A選了兩次某課程,所以還需要添加distinct來去重。
方法2:(優)
方法1使用臨時表是因爲count(student)不能直接在where子句中使用,方便爲count(student)重命名,這種方法完全可以,但是存在更優的方案,即使用having替換where
。
# 596. 超過5名學生的課
# 方法1:
select class from(
select class,count(distinct student) as "num"
from courses
group by class
) as temp_table
where num>=5;
# 方法2:(優)
select class
from courses
group by class
having count(distinct student)>=5;
620. 有趣的電影
題目鏈接: 點擊傳送至本題
題目大意:
有電影表cinema( id,movie,description,rating)
,要求查出影片描述(description字段)不是boring且id爲奇數的影片,結果按照登記rating降序排序。
解題思路:
影片描述description字段不是boring,可以使用運算符<>,id爲奇數可以使用mod取餘運算。
# 620. 有趣的電影
select *
from cinema
where description <> 'boring' and mod(id,2)=1
order by rating desc;
627. 交換工資
題目鏈接: 點擊傳送至本題
題目大意:
有salary(id,name,sex,salary)
表,其中的sex字段中m代表男性,f代表女性。要求:只使用一個更新(Update)語句且不適用臨時表,將所有的f和m值交換。
解題思路:
方法1:
使用if語句設置sex字段,如果字段等於f則替換爲m,否則替換爲f。
方法2:(優)
使用case語句設置sex字段,相比於使用if的方法,case效率更高一點,有空間換時間的意思。
# 627. 交換工資
# 方法1:
update salary
set sex=if(sex='f','m','f');
# 方法2:
update salary
set sex = case
when 'm' then 'f'
else 'm'
end;
1179. 重新格式化部門表
題目鏈接: 點擊傳送至本題
題目大意:
有Department(id,revenue,month)
表,要求:編寫一個sql查詢重新格式化表,使得新的表中有一個部門id列和一些對應每個月的收入(revenue)列,新表如下所示:
解題思路:
使用case語句在revenue中篩選對應的月份的revenue 作爲Month_Revenue,對每一個月份都進行篩選,通過group by可以實現對相同列進行合併處理。另外,之所以使用聚合函數sum是因爲case語句篩選時,除了篩選成功的那個數據,其他數據都會查詢爲null,返回結果會爲多條,聚合函數可以解決這一問題,除了sum,max,min等都可以解決這一問題。
# 1179. 重新格式化部門表
select id,
sum(case when month='Jan' then revenue end) as Jan_Revenue,
sum(case when month='Feb' then revenue end) as Feb_Revenue,
sum(case when month='Mar' then revenue end) as Mar_Revenue,
sum(case when month='Apr' then revenue end) as Apr_Revenue,
sum(case when month='May' then revenue end) as May_Revenue,
sum(case when month='Jun' then revenue end) as Jun_Revenue,
sum(case when month='Jul' then revenue end) as Jul_Revenue,
sum(case when month='Aug' then revenue end) as Aug_Revenue,
sum(case when month='Sep' then revenue end) as Sep_Revenue,
sum(case when month='Oct' then revenue end) as Oct_Revenue,
sum(case when month='Nov' then revenue end) as Nov_Revenue,
sum(case when month='Dec' then revenue end) as Dec_Revenue
from Department
group by id;
中等
626. 換座位
題目鏈接: 點擊傳送至本題
題目大意:
有座位表seat(id,student)
,要求寫出查詢語句,改變相鄰兩個學生的座位。如果學生人數是奇數,則不需要改變最後一個同學的座位。
解題思路:
使用case語句,針對座位id是奇數的同學,修改id爲+1,需額外考慮如果最後一個座位id是奇數時,不做修改;針對座位id是偶數的同學,修改id爲-1。最後一個座位id的奇偶性可以使用count(*)來判斷。全部完成之後,再使用升序將所有的數據重新排列。
# 626. 換座位
select (case
when mod(id,2) = 0 then id - 1
when mod(id,2) = 1 and id = (select count(*) from seat) then id
else id +1
end) as id,student
from seat
order by id asc;
困難
601. 體育館的人流量
題目鏈接: 點擊傳送至本題
題目大意:
有stadium表(id,visit_date,people)
,關於高峯期的定義是連續三行記錄中的人流量不少於100,要求編寫查詢語句,找出人流量的高峯期。
解題思路:
本題不難,只是較爲複雜。查找人流量的高峯期有兩個重要的條件:①連續三天
:連續三天可以通過自連接兩次,形成三張表的笛卡爾積,篩選時可以a表爲例,讓a分別作爲第一天、第二天、第三天,這樣纔可以考慮完整的情況。②人流量大於等於100
:讓三張表的people字段分別大於等於100。
注意:在最後除了要對查詢的字段添加distinct進行去重外,還需要對數據進行增量排序。
# 601. 體育館的人流量
select distinct a.*
from
stadium as a,
stadium as b,
stadium as c
where a.people>=100 and b.people>=100 and c.people>=100
and ((a.id+1 = b.id and b.id+1 = c.id)
or (b.id+1 = a.id and a.id+1 = c.id)
or (b.id+1 = c.id and c.id+1 = a.id))
order by a.id asc;
到這裏,LeetCode上可以免費刷的數據庫相關的題目就完畢了,接下來我會更新一波數據結構和算法相關的題目,等把免費的再刷完了(如果可以的話),到時候再開LeetCode會員刷會員題。