1. 程式人生 > >資料庫的一些常見面試題及其答案詳解

資料庫的一些常見面試題及其答案詳解

我先標明下面題目的轉載地址:原題目地址, 還有就是我所使用的資料庫是MySQL,但是SQL語法大部分相同,只有少部分與Oracle、SQL Server不同。

之前因為面試中吃了很多SQL 語法的虧了,決定真的要把這個玩會了,之前確實一直因為使用的都是hibernate框架,對資料庫原生SQL的操作太少了,所以現在對基本的查詢方式特別陌生。看到這套題目之後我還是覺得挺好的,最好是自己親自寫,不會的可以先看一下資料,瞭解基本的SQL 92 與 SQL 99語法以及資料庫分組和組函式之後再開始做題。如果一上來就直接看我的步驟和答案,可能沒效果,因為你可能過兩天就還給我了。好了,不說那麼多了,直接上菜吧:

1、

教師號  星期號 是否有課

 1    2   有

 1    3   有

 2    1   有

 3    2   有`

 1    2   有

寫一條sql語句讓你變為這樣的表

教師號 星期一 星期二 星期三

 1       2   1 

 2   1   

 3       1

解析步驟:首先建表,這裡是我建的表:

建表

然後也可看到我圖中後面的步驟(以teacher_id列進行升序排序),其實mysql自動就是升序排列。再對比題目要求,我們還需要對calendar列進行操作,對相同數值的行進行count(*)操作,但是要注意的是這個count操作是在我們現有執行上面這樣操作之後的資料表

,也就是要用到子查詢。所以接下來執行如下(這裡只是對calendar進行count操作):

僅對calendar進行count操作

仔細看這張表發現在calendar=2時總共有3節課,但是顯示的全是teacher_id為1的老師,顯然這個是錯誤的。這是因為我們需要的結果是:哪個老師哪一天有幾節課,而上面只有引數哪一天而忽略了哪個老師這個條件,所以這裡對後面group by新增一個條件:

增加teacher_id條件

這個看起來差不多了,但是看起來還是亂糟糟的,感覺還是以老師(teacher_id)來排序比較好,所以這裡再新增一個條件:

以老師排序

嗯!這個看起來還不錯的樣子。我覺得這個應該也是答案吧。

因為昨天晚上想著第二道題都到兩點了,所以沒繼續寫下去,今天補充上來。

2、

兩個表情況

表名:wu_plan 

ID      plan      model       corp_code     plannum     prixis

1       00001     exx22         nokia        2000         0

2       00002     lc001         sony         3000         0

表名:wu_bom

ID     plan       pact          amount    

1      00001      aa1            300

2      00001      aa2            200

3      00002      bb1            500

4      00002      bb2            800

5      00002      bb3            400

查詢這兩個表中plan唯一,每一個plan中,amount最少的,plannum大於prixis的記錄

結果是:

ID      plan      model       corp_code     plannum     prixis     pact   amount

1       00001     exx22         nokia        2000         0       a2       200

2       00002     lc001         sony         3000         0       bb3      400

這道題說實話還是有一些難度的,如果對join操作不熟悉的話,真不好解答,我現在這裡push出我參考的一道題目:select first row in each group by group 解題步驟:要查詢amount最少的,肯定要用到SQL的min函數了,然後我們現不看wu_plan,直接對wu_bom表進行操作:
mysql> select min(b.amount) as min_amount, b.plan from wu_bom b group by b.plan;
結果如下圖: 每個group中的最小amount
這裡可能有些人有點不理解為什麼不直接使用min(b.amount)後面要加上一個別名(min_amount)呢?因為這個min_amount在後面要作為我們與表wu_plan比較的根據,如果不設定別名,列名寫起來太麻煩了。那麼由上面sql 生成了每一組plan中的最小值,但是隻有這麼一個最小值還是不行的啊,因為題目的條件是每個wu_plan表中的最小資料,我們現在只是wu_bom表啊,那麼這時候需要進行:右連線+子查詢 很多人可能會問為什麼是這樣的操作呢?因為我們現在已經得到了上圖這樣的一個查詢檢視,條件也已經知道了(wu_plan中所有plan值為‘00001’的列行與‘00002’的行),這不就是一次右查詢的事嘛,我知道這裡我說的很不清楚,但是左右查詢網上有很多教程的,不熟悉的朋友還是好好看看吧。 下一步:
select p.*,y.min_amount from wu_plan p right join (select min(b.amount) as min_amount, b.plan from wu_bom b group by b.plan) y on p.plan = y.plan and p.plannum > p.prixis;
真相就出來了吧。結果如下圖: 查詢結果
當然有些同學又會說為什麼我在這個表中看到的全是wu_plan表資訊,我要想增加wu_bom表資訊(比如說增加pact列)怎麼辦,直接在子查詢(SQL語句中括號內增加你想要在結果看到的列)增加該列到縣市結果中就可了。
未完待續!