【關注微信公眾號:跟強哥學SQL,回復“筆試”免費領取大廠SQL筆試題。】
有兩個名為Department(部門)和Employees(員工)的表結構如下:?
CREATE TABLE Department (
DepId int,
DepName varchar (255),
????ParentDepID?int
);
CREATE TABLE Employees (
ID int,
Name varchar (255),
Age int,
????Birthday date,
Address varchar (255),
Salary decimal (18, 2),
ManagerId int,
????DepID?int
);
題目1:插入數據
題目:在Employees表中插入一條數據,ID為1, Name為’TOM', Age為30,出生日期為1990年3月10日,Address為’Guangzhou',Salary為8000,ManagerId為3,DepID為1。
答案:
INSERT INTO Employees
VALUES (1, 'TOM', 30, 'Guangzhou', 8000.00, 3, 1);
或
INSERT?INTO?Employees?(ID,?Name,?Age,?Birthday, Address,?Salary,?ManagerId,?DepID)?
VALUES?(1,?'TOM',?30,?'1990-03-10', 'Guangzhou',?8000.00,?3,?1);
解析:這是基本的插入語句,可以將需要插入的值放在VALUES()內,字段順序與TABLE定義順序匹配。
題目2:修改數據
題目:更新Employees表中ID為1的員工的工資為9000。
答案:
UPDATE Employees
SET Salary = 9000
WHERE ID = 1;
解析:使用Update語句進行數據的更新。可以通過Where子句限定需要修改的行。
題目3:刪除數據
題目:刪除Employees表中ID為1的全部信息。
答案:
DELETE FROM Employees
WHERE ID = 1;
解析:使用DELETE語句刪除特定的行,可以通過WHERE子句找到ID為1的行并刪除。
題目4:單表查詢
題目:查找Employees表中所有員工的ID和Name。
答案:
SELECT ID, Name
FROM Employees;
解析:使用SELECT語句實現單表查詢,選擇想要顯示的字段名稱。
題目5:條件查詢
題目:查找Employees表中所有薪水大于1萬的員工的ID和Name。
答案:
SELECT ID, Name
FROM Employees
WHERE Salary > 10000;
解析:使用WHERE語句,可以精確篩選出滿足條件的數據。
題目6:組合條件查詢(AND)
題目:查找Employees表中所有薪水大于1萬且年齡在30歲及以下的員工的ID和Name。
答案:
SELECT ID, Name
FROM Employees
WHERE Salary > 10000
AND Age <= 30;
解析:在WHERE語句中使用AND關鍵字組合多個條件,可以查詢出同時滿足多個條件的數據。
題目7:組合條件查詢(OR)
題目:查找Employees表中所有薪水大于1萬或年齡在30歲及以下的員工的ID和Name。
答案:
SELECT ID, Name
FROM Employees
WHERE Salary > 10000
OR?Age?<=?30;
解析:在WHERE語句中使用OR關鍵字組合多個條件,可以查詢出滿足任意一個條件的數據。
題目8:復雜組合條件查詢(AND + OR)
題目:查找Employees表中所有年齡在30歲及以下的員工中薪水大于3萬或小于5000的員工ID和Name。
答案:
SELECT ID, Name
FROM Employees
WHERE?(Salary?>?30000
OR?Salary < 5000)
AND Age?<=?30;
解析:在WHERE語句中使用AND和OR關鍵字,可以實現多個條件的復雜組合,此時可以使用小括號將多個條件放在一起優先計算。
題目9:字段拼接
題目:查詢Employees表,以“ID:Name”格式顯示員工的ID、Name。
答案:
SELECT CAST(ID as CHAR) || ':' || Name
FROM Employees;
或
SELECT?CONCAT(CAST(ID?as?CHAR),?':',?Name)
FROM Employees;
解析:使用||或CONCAT可以將多個字符串值拼接在一起。注意,如果待拼接的值不是字符串類型,需要使用轉換函數進行轉換后拼接。
題目10:數值計算
題目:為所有員工加薪10%。
答案:
UPDATE Employees
SET Salary = Salary * 1.1;
解析:對于數值類字段,可以進行加、減、乘、除等數值計算。
題目11:數據分段
題目:以小于1萬、1萬至3萬、3萬以上顯示所有員工的薪水區間而不是具體的薪水。
答案:
SELECT ID,
????CASE?WHEN?Salary?<=?10000?THEN?'小于1萬'
?????????WHEN?Salary?>=?30000?THEN?'3萬以上'
ELSE '1萬至3萬' END
FROM Employees
解析:可以使用CASE WHEN關鍵字,對滿足不同條件的值轉換返回值。
題目12:多表查詢(內連接)
題目:查詢Employees表和Department表,顯示員工的姓名、部門名稱。
答案:
SELECT e.Name, d.DepName
FROM Employees e
INNER?JOIN?Department?d?
ON e.DepId = d.DepId;
解析:這是一個基礎的內連接查詢,用于組合來自兩個或更多表的行。當關聯屬性在參與連接的兩張表中都存在時,數據才返回。
題目13:多表查詢(左連接)
題目:查詢Employees表和Department表,顯示員工的姓名、部門名稱。即使某員工未歸屬到任意一個部門下,也需要顯示。
答案:
SELECT e.Name, d.DepName
FROM Employees e
LEFT JOIN Department d
ON e.DepId = d.DepId;
解析:這是一個基礎的左連接查詢,用于組合來自兩個或更多表的行。當關聯屬性在參與連接的右表中不存在時,左表的數據也會返回,但來自右表的屬性會顯示為NULL。
題目14:多表查詢(右連接)
題目:查詢Employees表和Department表,顯示員工的姓名、部門名稱。即使某員工未歸屬到任意一個部門下,也需要顯示。
答案:
SELECT e.Name, d.DepName
FROM Department d
RIGHT JOIN Employees e
ON d.DepId = e.DepId;
解析:這是一個基礎的右連接查詢,它等價于題目6。
題目15:排序查詢(升序)
題目:查詢所有員工ID及員工姓名,并以薪水從低到高排序。
答案:
SELECT ID, Name
FROM Employees
ORDER?BY?Salary;
或
SELECT ID, Name
FROM Employees
ORDER BY Salary ASC;
解析:使用SELECT語句提取員工ID及員工姓名,并通過ORDER BY關鍵字按照薪水進行升序排序。
題目16:排序查詢(降序)
題目:查詢所有員工ID及員工姓名,并以薪水從高到低排序。
答案:
SELECT ID, Name
FROM Employees
ORDER?BY?Salary?DESC;
解析:使用SELECT語句提取員工ID及員工姓名,并通過ORDER BY關鍵字按照薪水進行降序排序。
題目17:排序查詢(組合排序)
題目:查詢所有員工ID及員工姓名,并以薪水從高到低、員工ID從小到大排序。
答案:
SELECT ID, Name
FROM Employees
ORDER?BY?Salary?DESC,?ID?ASC;
解析:使用SELECT語句提取員工ID及員工姓名,并通過ORDER BY關鍵字按照薪水降序、員工ID升序進行排序。
題目18:查詢前N行
題目:查詢所有員工ID及員工姓名,并以薪水從高到低排序,返回前10名。
答案:
SELECT ID, Name
FROM Employees
ORDER?BY?Salary?DESC
LIMIT 10;
解析:使用LIMIT可以返回前N行。
題目19:分頁查詢
題目:查詢所有員工ID及員工姓名,并以薪水從高到低排序,每10人為1頁,返回第3頁的數據。
答案:
SELECT ID, Name
FROM Employees
ORDER?BY?Salary?DESC
LIMIT?20,10;
解析:使用LIMIT時,可以先指定跳過的行數,再指定返回的行數。
題目20:自關聯
題目:查詢所有員工ID、員工姓名以及經理ID、經理姓名。
答案:
SELECT?a.ID,?a.Name, a.ManagerId, b.Name
FROM Employees a
INNER JOIN Employees b
ON?a.ManagerId?=?b.ID;
解析:自己與自己關聯,被稱為自關聯。常用于上下級等層級關系的查詢中。
題目21:集合運算(UNION)
題目:返回所有薪水大于1萬或年齡小于30的員工ID、員工姓名。同時滿足兩個條件的員工,僅返回1條記錄。
答案:
SELECT ID, Name
FROM Employees
WHERE Salary > 10000
UNION
SELECT ID, Name
FROM Employees
WHERE Age < 30;
解析:使用UNION關鍵字,可以返回兩個集合的并集。在返回之前會將相同的記錄去重。
題目22:集合運算(UNION?ALL)
題目:返回所有薪水大于1萬或年齡小于30的員工ID、員工姓名。同時滿足兩個條件的員工,返回2條記錄。
答案:
SELECT ID, Name
FROM Employees
WHERE Salary > 10000
UNION ALL
SELECT ID, Name
FROM Employees
WHERE Age < 30;
解析:使用UNION ALL關鍵字,可以返回兩個集合的并集。在返回之前不會將相同的記錄去重。
題目23:集合運算(EXCEPT或MINUS)
題目:返回薪水大于1萬但年齡不小于30的員工ID、員工姓名。
答案:
SELECT ID, Name
FROM Employees
WHERE Salary > 10000
EXCEPT
SELECT ID, Name
FROM Employees
WHERE Age < 30;
解析:使用EXCEPT關鍵字,可以從一個集合中排除部分數據。
題目24:集合運算(INTERSECT)
題目:返回薪水大于1萬且年齡小于30的員工ID、員工姓名。
答案:
SELECT ID, Name
FROM Employees
WHERE Salary > 10000
INTERSECT
SELECT ID, Name
FROM Employees
WHERE Age < 30;
解析:使用INTERSECT關鍵字,可以返回兩個集合的交集。
題目25:模糊查詢(包含關鍵字)
題目:查詢所有名字中包含“磊”字的員工ID和Name。
答案:
SELECT ID, Name
FROM Employees
WHERE?Name?LIKE '%磊%';
解析:LIKE關鍵字可以實現模糊查詢,%通配符用來匹配任意多個任意字符。
題目26:模糊查詢(以*開頭)
題目:查詢所有姓王的員工ID和Name。
答案:
SELECT ID, Name
FROM Employees
WHERE?Name?LIKE?'王%';
解析:使用LIKE關鍵字,可以查詢出指定前綴字符的數據。
題目27:模糊查詢(以*結尾)
題目:查詢所有姓名最后一個字為“磊”的員工ID和Name。
答案:
SELECT ID, Name
FROM Employees
WHERE?Name?LIKE?'%磊';
解析:使用LIKE關鍵字,可以查詢出指定后綴字符的數據。
題目28:模糊查詢(第二個字符為指定符號)
題目:查詢所有姓名第二個字為“磊”的員工ID和Name。
答案:
SELECT ID, Name
FROM Employees
WHERE?Name?LIKE?'_磊%';
解析:_下劃線通配符用來匹配任意一個字符。
題目29:模糊查詢(至少有3個字符)
題目:查詢所有姓名至少為3個字的員工ID和Name。
答案:
SELECT ID, Name
FROM Employees
WHERE?Name?LIKE?'___%';
解析:___三個下劃線用來匹配任意3個字符。
題目30:子查詢(IN)
題目:查詢薪水在3萬元以上的員工所在的部門ID和部門名稱。
答案:
SELECT DepId, DepName
FROM Department
WHERE?DepId IN (
SELECT DepID
????FROM Employees
????WHERE?Salary > 30000
);
解析:使用IN關鍵字,可以查詢存在于某個集合中的數據。
題目31:子查詢(NOT IN)
題目:查詢薪水在5000元以下的員工所在的部門ID和部門名稱。
答案:
SELECT DepId, DepName
FROM Department
WHERE?DepId NOT IN (
SELECT DepID
????FROM Employees
????WHERE?Salary > 5000
);
解析:使用NOT IN關鍵字,可以查詢不存在于某個集合中的數據。
題目32:子查詢(EXISTS)
題目:查詢薪水在3萬元以上的員工所在的部門ID和部門名稱。
答案:
SELECT DepId, DepName
FROM Department a
WHERE?EXISTS (
SELECT 1
????FROM Employees b
????WHERE?b.Salary > 30000
????AND a.DepId = b.DepId
);
解析:使用EXISTS關鍵字,可以查詢滿足某些條件的數據。
題目33:子查詢(NOT EXISTS)
題目:查詢不存在薪水在3萬元以上的員工的部門ID和部門名稱。
答案:
SELECT DepId, DepName
FROM Department a
WHERE?NOT EXISTS (
SELECT 1
????FROM Employees b
????WHERE?b.Salary > 30000
????AND a.DepId = b.DepId
);
解析:使用NOT EXISTS關鍵字,可以查詢不滿足某些條件的數據。
題目34:子查詢(SELECT中的子查詢)
題目:查詢員工ID、員工姓名以及員工所在的部門ID和部門名稱。
答案:
SELECT?ID,?Name, DepId,
????(
???? SELECT?b.DepName?FROM?Department b
???? WHERE a.DepId = b.DepId
????)
FROM?Employees?a;
解析:在SELECT子句中也可以使用子查詢。不過要注意,子查詢中查詢到滿足條件的數據只能小于等于1條,否則查詢可能會報錯。
題目35:聚合函數(MIN)
題目:查詢所有員工中的最小年齡。
答案:
SELECT?MIN(Age)
FROM?Employees?a;
解析:使用聚合函數MIN,可以查詢出最小值。
題目36:聚合函數(MAX)
題目:查詢所有員工中的最大年齡。
答案:
SELECT?MAX(Age)
FROM?Employees?a;
解析:使用聚合函數MAX,可以查詢出最大值。
題目37:聚合函數(AVG)
題目:查詢所有員工中的平均年齡。
答案:
SELECT?AVG(Age)
FROM?Employees?a;
解析:使用聚合函數AVG,可以查詢出平均值。
題目38:聚合函數(COUNT)
題目:查詢總的員工。
答案:
SELECT?COUNT(ID)
FROM?Employees?a;
或
SELECT COUNT(1)
FROM Employees a;
解析:使用聚合函數COUNT,可以對值進行計數(計數時,不計算NULL值)。
題目39:聚合函數(SUM)
題目:查詢所有員工的總薪水。
答案:
SELECT?SUM(Salary)
FROM?Employees?a;
解析:使用聚合函數SUM,可以對數值進行求和。
題目40:分組聚合(GROUP?BY)
題目:查詢每個部門下所有員工的總薪水。
答案:
SELECT?DepId,SUM(Salary)
FROM?Employees?a
GROUP BY DepId;
解析:使用GROUP BY關鍵字及聚合函數,可以實現將相同部門的員工分組后聚合。
題目41:對聚合結果進行篩選(HAVING)
題目:查詢平均薪水大于3萬的部門。
答案:
SELECT?DepId,SUM(Salary)
FROM?Employees?a
GROUP BY DepId
HAVING SUM(Salary) > 30000;
解析:使用HAVING關鍵字,可以對聚合后的結果進行篩選。
題目42:極值查詢(查詢最大值)
題目:查詢薪水最大的所有員工。
答案:
SELECT?*
FROM?Employees?a
WHERE?Salary?IN?(
SELECT MAX(Salary) FROM Employees
);
解析:先查出最大值,然后再篩選薪水為最大值的員工。
題目43:極值查詢(查詢最小值)
題目:查詢薪水最少的所有員工。
答案:
SELECT?*
FROM?Employees?a
WHERE?Salary?IN?(
SELECT MIN(Salary) FROM Employees
);
解析:先查出最小值,然后再篩選薪水為最小值的員工。
題目44:分析函數(ROW_NUMBER)
題目:查詢每個部門薪水前3名的員工。即使薪水相同,也只返回前3名。
答案:
SELECT?ID,RN
FROM?(
SELECT
ID,
????????ROW_NUMBER()?OVER(PARTITION?BY?DepId ORDER BY Salary DESC) RN
FROM Employees
)a
WHERE RN <= 3;
解析:先使用PARTITION BY關鍵字按部門分組,再使用ROW_NUMBER和ORDER BY計算出每位員工的排名,最后只篩選出前3名。當薪水相同時,隨機排名,所以返回的排名是連續且不重復的。
題目45:分析函數(RANK)
題目:查詢每個部門薪水前3名的員工。薪水相同,返回的排名相同,但只返回前3名。
答案:
SELECT?ID,RN
FROM?(
SELECT
ID,
????????RANK()?OVER(PARTITION?BY?DepId?ORDER?BY?Salary?DESC)?RN
FROM Employees
)a
WHERE RN <= 3;
解析:先使用PARTITION BY關鍵字按部門分組,再使用RANK和ORDER BY計算出每位員工的排名,最后只篩選出前3名。當薪水相同時,排名相同,但下一個排名序號將會被略過,所以返回的排名是不連續且重復的。
題目46:分析函數(DENSE_RANK)
題目:查詢每個部門薪水前3名的員工。薪水相同,返回的排名相同,排名需連續。
答案:
SELECT?ID,RN
FROM?(
SELECT
ID,
????????DENSE_RANK()?OVER(PARTITION?BY?DepId?ORDER?BY?Salary?DESC)?RN
FROM Employees
)a
WHERE RN <= 3;
解析:先使用PARTITION BY關鍵字按部門分組,再使用DENSE_RANK和ORDER BY計算出每位員工的排名,最后只篩選出前3名。當薪水相同時,排名相同,且下一個排名序號不會被略過,所以返回的排名是連續且重復的。
題目47:去重(GROUP BY)
題目:查詢每個部門下各有哪些年齡。
答案:
SELECT?DepId,Age
FROM Employees
GROUP BY DepId,Age;
解析:GROUP BY關鍵字用于分組,同一分組因為數值相同,所以只返回一條記錄。
題目48:去重(DISTINCT)
題目:查詢每個部門下各有哪些年齡。
答案:
SELECT?DISTINCT DepId,Age
FROM Employees
;
解析:DISTINCT關鍵字可以對指定的字段值直接進行去重。
題目49:隨機采樣查詢
題目:從員工表中隨機返回10條記錄,要求每次返回的結果盡量隨機分布。
答案:
SELECT *
FROM Employees
ORDER BY RAND()
LIMIT 10;
解析:RAND函數返回一個0~1之間的隨機值,使用隨機值排序,可以保證每次返回的行都是隨機的。
題目50:日期函數轉換
題目:統計出每個年份出生的員工數。
答案:
SELECT DATE_FORMAT(Birthday, '%Y'),count(*)
FROM Employees
GROUP BY DATE_FORMAT(Birthday, '%Y');
解析:Birthday字段的值為DATE類型,包含具體的年、月、日,所以在分組聚合前,需要使用DATE_FORMAT函數將DATE類型格式化取出年份后再統計。
【關注微信公眾號:跟強哥學SQL,回復“筆試”免費領取大廠SQL筆試題。】?