(sql語句試題練習及 參考答案解題思路+個人解題思路)


SQL字段說明及數據

=======================================================================
一、部門表字段描述:
dp_no 部門ID
dp_name 部門名稱
dp_loc 部門所在地

二、員工表字段說明:
eNo 員工編號
eName 員工姓名
eJob 員工職責
emgr 上司編號
eHiredate 入職時間
eSal 工資
ecomm 扣稅
dp_no 部門ID

創建數據庫及數據表
CREATE DATABASE IF NOT EXISTS SQLTEST;

CREATE TABLE IF NOT EXISTS dept(
dp_no int(10) not null primary key,
dp_name varchar(25),
dp_loc varchar(25)
);

CREATE TABLE IF NOT EXISTS EMP(
eNo int(25) not null primary key,
eName varchar(45),
eJob varchar(45),
emgr int(25),
eHiredate date,
eSal int(45),
ecomm int(45),
dp_no int(25)
);

 

添加dept表數據:
insert into dept(dp_no, dp_name, dp_loc) values (10, 'ACCOUNTING', 'NEW YORK');
insert into dept(dp_no, dp_name, dp_loc) values (20, 'RESEARCH', 'DALLAS');
insert into dept(dp_no, dp_name, dp_loc) values (30, 'eSalES', 'CHICAGO');
insert into dept(dp_no, dp_name, dp_loc) values (40, 'OPERATIONS', 'BOSTON');
commit;

添加EMP表數據: eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no
insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, null, 20);
insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7499, 'ALLEN', 'eSalESMAN', 7698,'1981-02-20', 1600, 300, 30);
insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7521, 'WARD', 'eSalESMAN', 7698, '1981-02-22', 1250, 500, 30);
insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7566, 'JONES', 'MANAGER', 7839, '1981-04-02' , 2975, null, 20);
insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7654, 'MARTIN', 'eSalESMAN', 7698, '1981-09-28' , 1250, 1400, 30);
insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01' , 2850, null, 30);
insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09' , 2450, null, 10);
insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7788, 'SCOTT', 'ANALYST', 7566, '1987-04-19' , 3000, null, 20);
insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7839, 'KING', 'PRESIDENT', null, '1981-11-17' , 5000, null, 10);
insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7844, 'TURNER', 'eSalESMAN', 7698, '1981-09-08' , 1500, 0, 30);
insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7876, 'ADAMS', 'CLERK', 7788, '1987-05-23' , 1100, null, 20);
insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7900, 'JAMES', 'CLERK', 7698, '1981-12-03' , 950, null, 30);
insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7902, 'FORD', 'ANALYST', 7566, '1981-12-02' , 3000, null, 20);
insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7934, 'MILLER', 'CLERK', 7782, '1982-01-23' , 5000, null, 10);

操作:

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

SQL基本操作案例
=======================================================================

老師給的問題及解題思路
【1】. 查詢出JONES的領導是誰(JONES向誰報告)。
子查詢(效率低):
select
eName
from
EMP where eNo in(select emgr from EMP where eName='JONES');

Join寫法(高效):
select
e2.eName
from(select emgr from EMP where eName='JONES') e1
left join EMP e2
on e1.emgr=e2.eNo;
=======================================================================
【2】.JONES領導誰。(誰向JONES報告)。
子查詢(效率低):
select
eName
from EMP
where emgr in (select emgr from EMP where eName='JONES');

Join寫法(高效):
select
e2.eName
from(select eNo from EMP where eName='JONES') e1
left join EMP e2
on e1.eNo=e2.emgr;
=======================================================================
【3】. 查詢各職位的員工工資的最大值,最小值,平均值,總和
(問題:下面好像是各部門的,上面的各職位的呢?-->eJob,各職位就應該更簡單,按職位分組)
第一步:
select eJob,max(eSal) as '最高薪資' from EMP group by eJob;
select eJob,min(eSal) as '最低薪資' from EMP group by eJob;
select eJob,avg(eSal) as '平均薪資' from EMP group by eJob;(要想保留小數點,round 里面不能寫as,寫到外面);
第二步:
select
eJob,
max(eSal) as '最低薪資',
min(eSal) as '最低薪資',
avg(eSal) as'平薪資均',
sum(eSal) as'總和'
from EMP
group by eJob;

====================================================================
【4】. 選擇具有各個eJob的員工人數(提示:對eJob進行分組,題目不太清楚覺得。。。)
select
eJob as '職務',
count(eJob) as '各職務人數'
from EMP
group by eJob;

【5】. 查詢員工最高工資和最低工資的差距,列名為DIFFERENCE;
select max(eSal)-min(eSal) as'DIFFERENCE' from EMP;
====================================================================
【6】. 查詢各個管理者屬下員工的最低工資,其中最低工資不能低於800,沒有管理者的員工
不計算在內
====================================================================
【7】. 查詢所有部門的部門名字dp_name,所在位置dp_loc,員工數量和工資平均值;
第一步:各部門編號、員工數量和工資平均值,作為一表,用Join思想!!!
select dp_no,count(eNO) as'員工數量',avg(eSal) as'工資平均' from EMP group by dp_no;
B、A、各部門編號、員工數量和工資平均值

select dp_name as'部門名',dp_loc as'位置',nums as'員工數量',avgeSal as'平均工資' from
(select dp_no as no,count(eNO) as nums ,avg(eSal) as avgeSal from EMP group by dp_no) e
left join dept d on d.dp_no=e.no;

select
d.dp_name as'部門名',
d.dp_loc as'位置',
e.nums as'員工數量',
e.avgeSal as'平均工資'
from dept d
left join (select dp_no as no,count(eNO) as nums ,avg(eSal) as avgeSal from EMP group by dp_no) e
on d.dp_no=e.no;

高效:和我寫的上面寫的有什么區別???
select
d.dp_name,
d.dp_loc,
count(eNO),
round(if(avg(eSal) is null,0,avg(eSal)),2) as'平均薪資'
from dept d
left join EMP e
on d.dp_no=e.dp_no
group by e.dp_no;

###round(xxx,2)保留兩位小數點
round(if(avg(eSal) is null,0,avg(eSal)),2) as'平均薪資'
#####判斷avg(eSal) is null,0,avg(eSal)為空時為0,否則用自己本身avg(eSal)
if(avg(eSal) is null,0,avg(eSal))

====================================================================
【8】. 查詢和scott相同部門的員工姓名eName和雇用日期eHiredate
普通寫法(效率低):
select
e.eName,
e.eHiredate
from EMP e
where dp_no=(select dp_no from EMP where eName='SCOTT');

Join寫法(高效):
select
e2.eName,
e2.eHiredate
from (select dp_no from EMP where eName='SCOTT') e1
left join EMP e2
on e1.dp_no=e2.dp_no;

====================================================================
【9】. 查詢工資比公司平均工資高的所有員工的員工號eNo,姓名eName和工資eSal。
子查詢(效率低):
select eNo as'編號',eName as'姓名',eSal as'薪資' from EMP where
eSal>(select avg(eSal) from EMP);

Join查詢(高效):
select
e2.eNO,
e2.eName,
e2.eSal
from (select avg(eSal) as avg from EMP) e1
left join EMP e2
on e1.avg<=e2.eSal;

====================================================================
【10】. 查詢和姓名中包含字母u的員工在相同部門的員工的員工號eNo和姓名eName
子查詢(效率低);
select
eNo as'編號',
eName as'姓名'
from EMP
where dp_no in (select dp_no from EMP Where eName like '%u%');

如果in寫為=號,返回的結果rows超過一行時會報下面錯誤,所以最好用in!
ERROR 1242 (21000): Subquery returns more than 1 row

Join查詢1(高效,包括又u字母的名字也都被查出來了):
select
e2.eNo,
e2.eName
from( select dp_no from EMP where eName like '%u%') e1
left join EMP e2
on e1.dp_no=e2.dp_no;

Join查詢2(高效,去掉包括有u字母的名字):
select
e2.eNo,
e2.eName
from(select dp_no,eName from EMP where eName like '%u%') e1
left join EMP e2
on e1.dp_no=e2.dp_no
where e1.eName!= e2.eName;
=================================================================
【11】. 查詢在部門dp_loc為newYork的部門工作的員工的員工姓名eName,
部門名稱dp_name和崗位名稱eJob

子查詢:
select
eName as'姓名',
dp_name as'部門',
eeJob as'職位'
from EMP e ,dept d
where e.dp_no =d.dp_no and d.dp_dp_loc='NEW YORK';

select
eName as'姓名',
dp_name as'部門',
eeJob as'職位'
from dept d
left join EMP e
on e.dp_no =d.dp_no
where d.dp_dp_loc='NEW YORK';

select
e.eName as'姓名',
d.dp_name as'部門',
e.eJob as'職位'
from(select dp_no,dp_name from dept where dept.dp_loc='NEW YORK') d
left join EMP e
on e.dp_no =d.dp_no;

====================================================================
【12】. 查詢管理者是king的員工姓名eName和工資eSal
select
eName as '姓名',
eSal as '薪資'
from EMP
where emgr in( select eNo from EMP where eName='KING');

select
e2.eName,
e2.eSal
from (select eNo from EMP where eName='KING') e1
left join EMP e2
on e1.eNo=e2.emgr;
====================================================================

【13】. 顯示ACCOUNTING部門有哪些職位
普通查詢:
select
eJob as'職位'
from dept d,EMP e
where d.dp_no=e.dp_no and d.dp_name='ACCOUNTING';

Join寫法:
select
e2.eJob as'職位'
from(select dp_no from dept where dp_name='ACCOUNTING') d
left join EMP e2
on d.dp_no=e2.dp_no

====================================================================

【14】. 各個部門中工資大於1500的員工人數及部門名稱

select
d.dp_name,
e.num as '薪資大於1500的各部門人數'
from (select dp_no ,count(eNo) as num from EMP Where eSal>1500 group by dp_no) e
left join dept d
on e.dp_no=d.dp_no;

====================================================================
【15】. 哪些員工的工資,高於整個公司的平均工資,列出員工的名字和工資(降序)
子查詢:
select
e.eName,
e.eSal
from EMP e
where eSal > (select avg(eSal) from EMP)
order by eSal desc;

Join寫法:
select
e2.eName as '高於整個公司的平均工資的員工姓名',
e2.eSal as '對應的薪資'
from(select avg(eSal) as avg from EMP) e1
left join EMP e2
on e2.eSal>e1.avg
order by e2.eSal desc;

====================================================================
【16】. 所在部門平均工資高於1500的員工名字
(如果部門的平均工資高於1500,輸出這個部門所有員工姓名)

select
e2.eName as '員工姓名'
from(select dp_no,avg(eSal) as avg from EMP group by dp_no having avg>1500) e1
left join EMP e2
on e2.dp_no=e1.dp_no;

select dp_no,avg(eSal) as avg from EMP group by dp_no having avg>1500
只能用having 不能用where,having是在做分組之后過濾
====================================================================

【17】. 列出各個部門中工資最高的員工的信息:員工名字、部門名稱、工資(有點問題哦)

子查詢:
select
eName as '姓名',
dp_no as '部門號',
eSal as '薪資'
from EMP where eSal in (select max(eSal) from EMP group by dp_no);

Join寫法:
select
e.eName as '姓名',
d.dp_name as '部門名稱',
e.es as '薪資'
from dept d
left join (select eName,dp_no,max(eSal) as es from EMP group by dp_no) e
on d.dp_no = e.dp_no;
====================================================================

【18】. 哪個部門的平均工資是最高的,列出部門號、平均工資

select
dp_no,
avg(eSal) as esal
from EMP
group by dp_no
order by esal desc
limit 1;

有兩個以上的部門平均薪資都是最高的怎么辦?
====================================================================
max怎么實現?思路:分組找到各部門平均薪資、部門號表e1,在從中找出最大值做表2為左表
又用類似於表e1作為右邊表
select
e3.dp_no,
e3.avg
from
(
select
max(e1.avg) as max
from(select dp_no,avg(eSal) as avg from EMP group by dp_no) e1
)e2
left join(select dp_no,avg(eSal) as avg from EMP group by dp_no) e3
on e2.max=e3.avg;

select

from(select
e1.avg as avg_max
from(select dp_no,avg(eSal) as avg from EMP group by dp_no) e1) e2

left join

 ---------------------------------------------------------------------------------------------------

個人解題思路:

-- 1.查詢出JONES的領導是誰
SELECT emgr FROM EMP WHERE eName='JONES' -- 根據員工姓名查詢領導編號
SELECT eName FROM EMP WHERE eNo=7839 -- 根據員工編號查詢員工姓名
-- 合並
SELECT eName FROM EMP WHERE eNo=(
SELECT emgr FROM EMP WHERE eName='JONES')
-- 2.JONES領導誰。
SELECT eNo FROM EMP WHERE eName='JONES' -- 根據員工姓名查找員工編號
SELECT eNo FROM EMP WHERE emgr=7566 -- 根據員工編號查找員工姓名
SELECT eName FROM EMP WHERE eNo IN(
SELECT eNo FROM EMP WHERE emgr=7566 ) -- 根據上司編號查找員工姓名

SELECT eName FROM EMP WHERE eNo IN(
SELECT eNo FROM EMP WHERE emgr=
(SELECT eNo FROM EMP WHERE eName='JONES') ) -- 根據上司姓名查找員工

-- 3.查詢各職位的員工工資的最大值,最小值,平均值,總和
SELECT eSal,eJob FROM EMP -- 各職位員工工資
SELECT MAX(eSal),eJob FROM EMP GROUP BY eJob -- 各職位員工工資最大值
SELECT MIN(eSal),eJob FROM EMP GROUP BY eJob -- 各職位員工工資最小值
SELECT AVG(eSal),eJob FROM EMP GROUP BY eJob -- 各職位員工工資平均值
SELECT SUM(eSal),eJob FROM EMP GROUP BY eJob -- 各職位員工工資總和
-- 4.選擇具有各個eJob的員工人數
-- 理解:查詢選擇各eJob的員工人數
SELECT COUNT(eNo),eJob FROM EMP GROUP BY eJob
-- 5.查詢員工最高工資和最低工資的差距,列名為DIFFERENCE
SELECT MAX(eSal) FROM EMP -- 查詢員工最高工資
SELECT MIN(eSal) FROM EMP -- 查詢員工最低工資
SELECT (MAX(eSal) - MIN(eSal))AS DIFFERENCE FROM EMP
-- 6.查詢各個管理者屬下員工的最低工資,其中最低工資不能低於800,沒有管理者的員工
-- 不計算在內

-- 首先查詢管理者都有哪些員工,再計算員工的最低工資,並且最低工資不能低於800,以管理者編號分組
SELECT emgr FROM EMP GROUP BY emgr -- 查詢各個管理者編號
-- 通過管理者編號查詢員工編號,員工姓名,管理者編號,員工最低工資,以管理者編號分組
SELECT eNo,eName,emgr,MIN(eSal) FROM EMP WHERE emgr IN(
SELECT emgr FROM EMP GROUP BY emgr) GROUP BY emgr HAVING MIN(eSal)>=800

-- 7.查詢所有部門的部門名字dp_name,所在位置dp_loc,員工數量和工資平均值
-- 查詢所有部門的部門名字,所在位置
SELECT dp_name,dp_loc FROM dept
-- 根據部門id查詢員工數量
SELECT COUNT(eNo) FROM
-- 內連接查詢,分組查詢
SELECT d.dp_name,d.dp_loc,COUNT(eNo),AVG(eSal) FROM EMP e INNER JOIN dept d
ON d.dp_no =e.dp_no GROUP BY d.dp_no
-- 8.查詢和scott相同部門的員工姓名eName和雇用日期eHiredate
-- 查詢scott所在部門id
SELECT dp_no,eName FROM EMP WHERE eName='scott'
-- 根據部門id查詢員工姓名和雇佣日期
SELECT eName,eHiredate FROM EMP WHERE dp_no IN(
SELECT dp_no FROM EMP WHERE eName='scott')

-- 9.查詢工資比公司平均工資高的所有員工的員工號eNo,姓名eName和工資eSal
SELECT AVG(eSal) FROM EMP -- 查詢公司平均工資
SELECT eSal FROM EMP GROUP BY eNo -- 查詢公司員工工資
SELECT eNo FROM EMP HAVING eSal>AVG(eSal) -- 錯
SELECT eNo,eName,eSal FROM EMP WHERE eSal>(SELECT AVG(eSal) FROM EMP) -- 正確
-- 10.查詢和姓名中包含字母u的員工在相同部門的員工的員工號eNo和姓名eName
-- 查詢姓名中包含字母u的員工及所在部門id
SELECT eName,eNo,dp_no FROM EMP WHERE eName LIKE 'u%' OR eName LIKE '%u%' OR eName LIKE '%u'
-- 根據部門id查詢該部門中的員工號和姓名
SELECT eName,eNo FROM EMP WHERE dp_no=30
-- 合並
SELECT eName,eNo FROM EMP WHERE dp_no IN(
SELECT dp_no FROM EMP WHERE eName LIKE 'u%' OR eName LIKE '%u%' OR eName LIKE '%u')

-- 11.查詢在部門dp_loc為newYork的部門工作的員工的員工姓名eName,
-- 部門名稱dp_name和崗位名稱eJob

-- 查詢部門名稱為newYork的部門id
SELECT dp_no FROM dept WHERE dp_loc='NEW YORK'
-- 查詢部門dp_loc為newYork的部門工作的員工的員工姓名eName
SELECT eName FROM EMP WHERE dp_no=10
-- 合並
SELECT eName FROM EMP WHERE dp_no IN(
SELECT dp_no FROM dept WHERE dp_loc='NEW YORK')

-- 12.查詢管理者是king的員工姓名eName和工資eSal
-- 查詢king的員工編號
SELECT eNo FROM EMP WHERE eName='KING' -- 7839
-- 查詢上司編號是7839的員工姓名,工資eSal
SELECT eName,eSal FROM EMP WHERE emgr=7839
-- 合並
SELECT eName,eSal FROM EMP WHERE emgr IN(
SELECT eNo FROM EMP WHERE eName='KING')

-- 13.顯示ACCOUNTING部門有哪些職位
-- 查詢ACCOUNTING部門的部門id
SELECT dp_no FROM dept WHERE dp_name='ACCOUNTING' -- 10
-- 查詢部門id為10的職位有哪些
SELECT eJob FROM EMP WHERE dp_no=10
-- 合並
SELECT eJob FROM EMP WHERE dp_no IN(
SELECT dp_no FROM dept WHERE dp_name='ACCOUNTING')

-- 14.各個部門中工資大於1500的員工人數及部門名稱
-- 查詢工資大於1500的員工編號和部門編號
SELECT eNo,dp_no FROM EMP WHERE eSal>1500
-- 查詢各個部門編號工資大於1500的員工人數
SELECT COUNT(eNo),dp_no FROM EMP WHERE eSal>1500 GROUP BY dp_no
-- 根據部門編號查詢部門名稱
SELECT dp_name FROM dept WHERE dp_no=10

-- 使用內連接查詢,分組查詢,條件查詢
SELECT COUNT(eNo),d.dp_name FROM EMP e INNER JOIN dept d ON d.dp_no=e.dp_no
WHERE eSal>1500 GROUP BY d.dp_no

-- 15.哪些員工的工資,高於整個公司的平均工資,列出員工的名字和工資(降序)
-- 同第九題
SELECT eNo,eName,eSal FROM EMP WHERE eSal>(SELECT AVG(eSal) FROM EMP) ORDER BY eSal DESC

-- 16.所在部門平均工資高於1500的員工名字,部門編號
SELECT eNo,dp_no FROM EMP WHERE eSal>1500
-- +部門名字
SELECT e.eName,e.eSal,d.dp_name FROM EMP e INNER JOIN dept d ON d.dp_no=e.dp_no
GROUP BY e.eNo HAVING AVG(eSal)>1500

-- 17.列出各個部門中工資最高的員工的信息:員工名字、部門名稱、工資
-- 各部門工資最高的員工編號
SELECT MAX(eSal),dp_no,eName FROM EMP GROUP BY dp_no
-- 內連接,分組查詢,聚合函數
SELECT MAX(eSal),eName,d.dp_name,d.dp_no FROM EMP e INNER JOIN dept d ON e.dp_no=d.dp_no GROUP BY d.dp_no

-- 18.哪個部門的平均工資是最高的,列出部門號、平均工資
-- 查詢各部門平均工資
SELECT AVG(eSal) FROM EMP GROUP BY dp_no
-- 查詢平均工資最高的部門號,最高平均工資
SELECT MAX(b),a.dp_no FROM (SELECT AVG(eSal)AS b,dp_no FROM EMP GROUP BY dp_no)AS a
-- +部門名稱
SELECT MAX(b),a.dp_no,d.dp_name FROM (SELECT AVG(eSal)AS b,dp_no FROM EMP GROUP BY dp_no)AS a INNER JOIN dept d ON d.dp_no=a.dp_no

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM