圖解面試題:如何找到喜歡的電影?
【題目】
某電影平臺(類似豆瓣、貓眼電影)用3個表來記錄電影資訊。“電影表”中是電影編號、電影名稱、電影描述資訊。
“類別表”是電影分類資訊,類別包括:犯罪電影、愛情電影、科幻電影。
“電影類別表”是對應電影(電影表中的電影編號)屬於哪一類(類別表中的電影類別編號)
查詢“電影表”中電影描述資訊包含“機器人”的電影,以及對應的電影類別名稱和電影數目(count(電影表.電影編號))。
同時,還需要該電影類別名稱對應電影數量(count(電影類別表.電影類別編號))>=5部。
【解題思路】
我們首先觀察輸出格式要求:
"機器人"是電影描述資訊裡面包含的內容,在“電影表”中。電影類別名稱在“類別表”中,因此需要將兩個表聯結。
而觀察三個表的列名,我們發現“電影表”和“類別表”沒有相同的列名,因此無法直接進行聯結,需要藉助“電影類別表”進行3表聯結。
使用哪種聯結呢?拿出《猴子 從零學會SQL》裡面的多表聯結圖。
因為取的是這些表的共同資料,所以使用內聯結。三表聯結隊員的sql如下:
select *
from 電影表 as f inner join 電影類別表 as fc
on f.電影編號 = fc.電影編號
inner join 類別表 as c
onfc.電影類別編號=c.電影類別編號;
1.查詢電影描述資訊中包含"機器人"的電影類別名稱
描述資訊中包含"機器人",需要用到字串模糊查詢(like)。拿出《猴子 從零學會SQL》裡面講過的字串模糊查詢知識點。
此題是描述資訊中包含"機器人",所以應該是 like '%機器人%'。使用where和like進行模糊查詢,結果如下:
select *
from 電影表 as f inner join 電影類別表 as fc
on f.電影編號 = fc.電影編號
inner join 類別表 as c
onfc.電影類別編號=c.電影類別編號
where f.電影描述資訊 like '%機器人%';;
2.上述電影類別名稱對應的電影數量(電影類別表.電影類別編號)>=5部
按照輸出格式要求,我們會想到先分組(按電影類別,group by c.電影類別名稱)彙總(電影數量,count(f.電影編號)),再用having子句對分組結果進行篩選(havingcount(c.電影類別編號)>=5)。
selectc.電影類別名稱,count(f.電影編號) as 電影數目
from 電影表 as f inner join 電影類別表 as fc
on f.電影編號 = fc.電影編號
inner join 類別表 as c
on fc.電影類別編號 = c.電影類別編號
where f.電影描述資訊 like '%機器人%'
group by c.電影類別名稱
havingcount(c.電影類別編號)>=5;
可以看出結果為Null了,是這樣嗎?
下圖紅色部分中的科幻類別對應的電影數量為5也滿足這些條件,但是為什麼按照上述語句得出的結果Null?
因為該題有個陷阱:按照題目順序,我們容易先用where和like查找出對應的電影,最後再用having count(電影類別編號) >= 5來篩選,最後會發現結果為Null。
但是,《猴子 從零學會SQL》裡講過的SQL執行順序是這樣的:
會先執行where子句,此時結果只有一行了:
所以count(電影類別編號) = 1,再用having count(電影類別編號) >= 5來篩選結果只會是Null。
而題目中的上述分類對應電影數量>=5部,是指該電影類別在原始表中的電影數量>= 5,而不是先用where子句篩選以後的表。
那麼,這就需要把having子句放在where子句之前,如何到呢?
也就是,需要先對原始表使用條件(電影類別名稱對應的電影數量>=5部)篩選資料,然後再執行條件(電影描述資訊包含“機器人”的電影對應的電影類別名稱以及電影數目)篩選資料。
這就需要把用having子句篩選出的資料作為臨時表。所以,正確的答題步驟修改為以下內容。
1.查詢出電影類別編號數量大於5的電影類別編號作為臨時表(記為右表)。
select 電影類別編號
from 電影類別表
group by 電影類別編號
having count(電影類別編號) >= 5;
(右表)
2.與前面已經內聯結的三個表(左表)通過電影類別編號再進行聯結。
(左表)
用哪種聯結方式呢?
因為要用到電影類別編號數量大於5的電影類別編號,右表為篩選後的結果。因此需要用到右聯結,只保留右表的全部資料,即電影類別編號為3的資料。
3.查詢電影描述資訊中包含"機器人"的電影
在上一步sql中加入where子句,進行模糊查詢
4.根據輸出格式要求選擇對應的列並用group by對電影類別名稱分組
最終sql如下:
select c.電影類別名稱,count(f.電影編號) as 電影數目
from 電影表 as f inner join 電影類別表 as fc
on f.電影編號 = fc.電影編號
inner join 類別表 as c
on fc.電影類別編號 = c.電影類別編號
right join (select 電影類別編號
from 電影類別表
group by 電影類別編號
having count(電影類別編號) >= 5) as cc
on fc.電影類別編號 = cc.電影類別編號
where f.電影描述資訊 like '%機器人%'
group by c.電影類別名稱;
【本題考點】
1.考查多表聯結。需要知道什麼情況下使用哪種聯結。
2.模糊查詢like
3.考查sql的執行順序,記住下面這張圖。
【舉一反三】
從下面的科目表中查詢姓“猴”的學生對應的科目型別以及科目數量。同時,還需要滿足該科目型別對應的科目數量大於或等於3。
select a.科目型別,count(a.科目) as 科目數量
from 科目表 as a
right join (select 科目型別
from 科目表
group by 科目型別
having count(科目型別) >= 3) as b
on a.科目型別 = b.科目型別
where 姓名 like '猴%'
group by a.科目型別;
推薦:如何從零學會sql?