MySQL面試試題(二)

第二次總結MySQL相關知識點及實際操作,做起題來感覺比上次有進步。後續將繼續更新,力求達到進一步熟練掌握。這一次就跳過正則表達式了,下次專門作爲一節。

一、使用通配符與創建計算字段

1.通配符

前面的所有的操作符都是針對已知值進行過濾的,不管是匹配一個值還是多個值,測試值是大於還是小於已知值,或者檢查某個範圍的值,共同點是過濾中使用的值都是已知的。如果遇到,比如搜索產品中包含文本anvil的所有產品,該怎麼查詢呢?
百分號(%)通配符: 在搜索串中,%表示任何字符出現的任意次數。
找到以jet開頭的產品:

SELECT prod_id,prod_name
FROM   products
WHERE  prod_name  LIKE  'jet%';

*搜索模式’%anvil%'表示匹配任何位置包括文本anvil的值,不管它之前或之後出現什麼字符:

SELECT prod_id,prod_name
FROM   products
WHERE  prod_name  LIKE  '%anvil%';

總之,%表示搜索模式中給定位置的0個、1個或多個字符。
下劃線(__)通配符: 下劃線的用途與%一樣,但下劃線只能匹配單個字符而不是多個字符。

SELECT prod_id,prod_name
FROM   products
WHERE  prod_name LIKE '_ ton anvil';

注意: _與後面的字母有一個空格。
結果:
在這裏插入圖片描述
與使用%通配符相比較:

SELECT prod_id,prod_name
FROM   products
WHERE  prod_name LIKE '% ton anvil';

結果:
在這裏插入圖片描述

2.創建計算字段

存儲在數據庫表中的數據一般不是應用程序所需要的格式,比如,如果想在一個字段中既顯示公司名,又顯示公司的地址,但這兩個信息一般包括在不同的的表列中。
拼接字段: 拼接:將值聯結到一起構成單個值。解決辦法是把兩個列拼接起來,使用Concat()函數來拼接兩個列。

SELECT    CONCAT(vend_name,'(',vend_country,')')
FROM      vendors
ORDER BY  vend_name; 

結果:
在這裏插入圖片描述
使用RTrim()函數去掉值右邊的所有空格。

SELECT    CONCAT(RTrim(vend_name),'(',RTrim(vend_country),')')
FROM      vendors
ORDER BY  vend_name;

結果:
在這裏插入圖片描述
使用別名: 別名:是一個字段或值的替換值。

SELECT    CONCAT(RTrim(vend_name),'(',RTrim(vend_country),')') AS vend_title
FROM      vendors
ORDER BY  vend_name;

結果:
在這裏插入圖片描述
執行算術計算:
檢索訂單號20005中的所有物品:

SELECT   prod_id,quantity,item_price
FROM     orderitems
WHERE    order_num = 20005;

結果:
在這裏插入圖片描述

SELECT   prod_id,quantity,item_price,quantity*item_price AS expanded_price
FROM     orderitems
WHERE    order_num = 20005;

結果:
在這裏插入圖片描述
常見的MySQL算術操作符:
在這裏插入圖片描述

二、經典面試題16-30

USE studydata;
-- 16、向SC表中插入一些記錄,這些記錄要求符合以下條件:沒有上過編號“003”課程的同學的學號、002號課的平均成績

-- 17、按平時成績從高到低顯示所有學生的“數據庫”、“企業管理”、“英語”三門課的成績,按如下顯示:學生ID,數據庫,企業管理,英語,有效課程數,有效平均分
SELECT a.Sid AS ID,
(SELECT b.score FROM SC b WHERE a.Sid = b.Sid AND b.Cid = 2019001) AS '數據庫',
(SELECT c.score FROM SC c WHERE c.Cid = 2019002 AND c.Sid = a.Sid limit 1) AS '企業管理',
(SELECT d.score FROM SC d WHERE d.Cid = 2019003 AND d.Sid = a.Sid LIMIT 1) AS '英語',
count(a.Cid) AS '有效課程數',
AVG(a.score) AS '有效平均分' 
FROM SC a
GROUP BY a.Sid
ORDER BY AVG(a.score) DESC;

-- 18、查詢各科成績最高和最低分:一如下形式顯示:課程ID、最高分、最低分
SELECT Cid AS ID,MAX(score)AS max_score,MIN(score) AS min_score
FROM SC 
GROUP BY Cid;

-- 19、按各科平均成績從低到高和優秀率(90以上)的百分數從高到低順序
-- 使用了CASE WHEN ...THEN...ELSE...END語句
SELECT a.Cid,b.Cname,IFNULL(AVG(a.score),0)AS AVG_Score,100*SUM(CASE WHEN IFNULL(a.score,0) >= 90 THEN 1 ELSE 0 END)/COUNT(*)+'%d' AS 'Percent'
FROM SC a,course b
WHERE a.Cid = b.Cid
GROUP BY a.Cid
ORDER BY AVG(score);

-- 20、查詢如下課程平均成績和優秀率的百分數(備註:需要在一行顯示):企業管理(001)、馬克思(002)、00&UML(003):
-- 重點是一行顯示
SELECT SUM(CASE WHEN Cid = '2019001' THEN score ELSE 0 END)/SUM(CASE WHEN Cid = '2019001' THEN 1 ELSE 0 END) AS '企業管理平均成績',
       100*SUM(CASE WHEN Cid = '2019001' AND score >=90 THEN 1 ELSE 0 END)/SUM(CASE WHEN Cid = '2019001' THEN 1 ELSE 0 END) AS '企業管理優秀率',
       SUM(CASE WHEN Cid = '2019002' THEN score ELSE 0 END)/SUM(CASE WHEN Cid = '2019002' THEN 1 ELSE 0 END) AS '馬克思平均成績',
       100*SUM(CASE WHEN Cid = '2019002' THEN score ELSE 0 END)/SUM(CASE WHEN Cid = '2019002' THEN 1 ELSE 0 END) AS '馬克思優秀率',
       SUM(CASE WHEN Cid = '2019003' THEN score ELSE 0 END)/SUM(CASE WHEN Cid = '2019003' THEN 1 ELSE 0 END) AS 'OO&UML平均成績',
       100*SUM(CASE WHEN Cid = '2019003' AND score >=90 THEN 1 ELSE 0 END)/SUM(CASE WHEN Cid = '2019003' THEN 1 ELSE 0 END) AS 'oo&UML優秀率'
FROM SC;

-- 21、查詢不同老師所教不同課程平均分從高到低顯示 
-- 使用分組 +聚集函數
SELECT c.Tname,a.Cname,IFNULL(AVG(b.score),0) AS Ave_score
FROM course a,SC b,Teacher c
WHERE a.Cid = b.Cid AND a.Tid = c.Tid
GROUP BY b.Cid
ORDER BY AVG(score) DESC;

-- 22、查詢如下課程成績第 3 名到第 6 名的學生成績單:企業管理(001),馬克思(002),UML (003)
-- 此題感覺題目有點晦澀難懂
SELECT Sid,score
FROM SC 
WHERE Cid = '2019001'
ORDER BY score DESC LIMIT 2,6;

-- 23、統計列印各科成績,各分數段人數:課程ID,課程名稱,[100-95],[95-80],[80-70],[ <70] 
-- 使用分組+CASE WHEN...THEN... ELSE... END 的用法
SELECT s.Cid,c.Cname,
SUM(CASE WHEN s.score <=100 AND s.score > 95 THEN 1 ELSE 0 END) AS '100-95',
SUM(CASE WHEN s.score <=95 AND s.score >80 THEN 1 ELSE 0 END) AS '95-80',
SUM(CASE WHEN s.score <=80 AND s.score >70 THEN 1 ELSE 0 END) AS '80-70',
SUM(CASE WHEN s.score <70 THEN 1 ELSE 0 END) AS '<70'
FROM SC s,course c
WHERE  s.Cid = c.Cid
GROUP BY s.Cid;

-- 24、查詢學生平均成績及其名次 
-- 難點在於排名,思路是:記錄每一個同學的平均成績,存在比它大的平均成績的個數,就是它前面排了多少個人,加1就是此時這個人的名次
SELECT (SELECT COUNT(a_avg)
        FROM   (SELECT Sid,AVG(score) AS a_avg
                FROM   SC 
                GROUP BY Sid) AS 	T1
        WHERE   a_avg > b_avg)+1 AS 'rank',
        T2.Sid,Sname,b_avg
FROM  (SELECT Sid,AVG(score) AS b_avg
       FROM   SC 
       GROUP BY Sid) AS T2,Students s
WHERE T2.Sid = s.Sid
ORDER BY b_avg DESC;

-- 25、查詢各科成績前三名的記錄:(不考慮成績並列情況)
SELECT  *
FROM    (SELECT Cid,Sid,score,row_number() over(PARTITION by Cid ORDER BY score DESC) AS fid FROM SC) AS T
WHERE   fid  <=3;

-- 26、查詢每門課程被選修的學生數;
SELECT s.Cid,Cname,COUNT(Sid)
FROM   SC s INNER JOIN Course c
ON s.Cid = c.Cid
GROUP BY  Cid;
-- 27、查詢出只選修了二門課程的全部學生的學號和姓名;
SELECT  sc.Sid ID,Sname Name
FROM    SC sc INNER JOIN Students st
ON      sc.Sid = st.Sid
GROUP BY  sc.Sid
HAVING COUNT(Cid)=2;

-- 28、查詢男生、女生的人數;
SELECT  (SUM(CASE WHEN Ssex='男' THEN 1 ELSE 0 END)) AS '男',
        (SUM(CASE WHEN Ssex='女' THEN 1 ELSE 0 END)) AS '女'
FROM    Students;

-- 29、查詢姓“李”的學生名單;
-- 使用通配符進行過濾
SELECT  Sname
FROM    Students
WHERE   Sname LIKE '李%';

-- 30、查詢同名同姓學生名單,並統計同名人數;
INSERT INTO Students(Sid,Sname,Sage,Ssex)  VALUES (1009,'趙雷','1997-07-12','男');
UPDATE  Students SET  Sname ='趙  雷' WHERE Sid = 1009;
SELECT * FROM  Students;

SELECT  Sname,COUNT(*)
FROM    Students 
GROUP BY  Sname
HAVING  COUNT(*) > 1;

參考資料:
1.sql面試題:https://www.cnblogs.com/qixuejia/p/3637735.html
2.SQL數據庫面試題以及答案(50例題):https://blog.csdn.net/u010154380/article/details/78412457/
3.SQL數據庫面試題以及答案(50例題優化版-增加圖片):你必知必會的SQL語句練習:https://blog.csdn.net/HD243608836/article/details/78784799

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章