1. 程式人生 > >MySql_34道經典Sql試題

MySql_34道經典Sql試題

from copyright update ges mysql 直接 info 1.2 class


MySql_34道經典Sql試題

版權聲明:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/xiaouncle/article/details/79939040

如果能流暢地把這34道題解答出來的話,那對於大多數開發者來說就不會再為寫Sql語句而煩惱,寫復雜的Sql語句時要分步驟完成,逐步擊破最終就能得到你想要的東西。看完這兩篇文章不代表你已經學會了,這只是個小小的開端而已。

準備工作

-- Employee中有Bonus=null記錄
-- in(nul1,200)只能查詢到Bonus=200的記錄
SELECT * FROM test.employee where Bonus in(null,200);

-- Employee中有Bonus=null記錄
-- not in(200,40)查詢結果會自動把Bonus=null的記錄過濾掉
-- not in(200,40,null)查詢結果為空
SELECT * FROM test.employee where Bonus not in(200,40);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

一、取得每個部門拿最高薪水的人員名稱

1、先取得各部門的最高薪水
2、再獲取各部門拿最高薪水的人員名稱
3、註意:每個部門拿最高薪水的有可能是多個人

select Employee.EmployeeName,Employee.DeptNo,Employee.Salary from Employee
inner join (select DeptNo,max(Salary)as maxSalary from Employee group by DeptNo) as b
on Employee.DeptNo=b.DeptNo and Employee.Salary=b.maxSalary;
  • 1
  • 2
  • 3

二、哪些人的薪水在部門平均薪水之上

1、先取得各部門的平均薪水
2、再獲取薪水在部門平均薪水之上的人

/*方法1*/
select Employee.EmployeeName,Employee.DeptNo,Employee.Salary from Employee
inner join (select DeptNo,avg(Salary)as avgSalary from Employee group by DeptNo) as b
on Employee.DeptNo=b.DeptNo and Employee.Salary>b.avgSalary;

/*方法2*/
select Employee.EmployeeName,Employee.DeptNo,Employee.Salary from Employee
inner join (select DeptNo,avg(Salary)as avgSalary from Employee group by DeptNo) as b
on Employee.DeptNo=b.DeptNo 
where Employee.Salary>b.avgSalary
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

三、取得部門中所有人的平均薪水等級

1、先取得各部門的平均薪水
2、再獲取各部門的平均薪水的等級

select a.DeptNo,a.avgSalary,b.Grade 
from (select DeptNo,avg(Salary)as avgSalary from Employee group by DeptNo) as a
left join SalaryGrade as b
on a.Salary between b.Lowest and b.Highest;
  • 1
  • 2
  • 3
  • 4

四、不用max()取得最高薪水

1、按照薪水將序排列,取第一項

select Id,EmployeeName,Salary from Employee order by Salary desc
limit 0,1;
  • 1
  • 2

1、獲取非最高薪水的員工Id(自己的薪水<其他人的薪水)
2、查詢Id不在非最高薪水員工Id列表的數據

select Id,EmployeeName,Salary from Employee
where Id not in(
    select distinct a.Id from Employee as a
    inner join Employee as b
    on a.Salary<b.Salary
);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

五、取得平均薪水最高的部門的部門編號

1、按照部門平均薪水將序排列,取第一項
2、註意:這種方式獲取到的確實是平均薪水最高的部門,但是如果有多個部門的平均薪水並列最高時,這種方式就不適用了

select DeptNo,avg(Salary)as avgSalary from Employee group by DeptNo order by avgSalary desc
limit 0,1;
  • 1
  • 2

1、先獲取各部門中最高的平均薪水
2、再獲取部門平均薪水等於部門最高平均薪水的部門信息

select DeptNo,avg(Salary)as avgSalary from Employee group by DeptNo
having avgSalary=(
    select avg(Salary)as maxAvgSalary from Employee group by DeptNo order by maxAvgSalary desc
    limit 0,1
);
  • 1
  • 2
  • 3
  • 4
  • 5

六、取得平均薪水最高的部門的部門名稱

1、先獲取各部門中最高的平均薪水
2、再獲取部門平均薪水等於部門最高平均薪水的部門編號
3、最後獲取平均薪水最高的部門的部門名稱

/*方法1*/
select a.DeptNo,b.DName,a.avgSalary from (select DeptNo,avg(Salary)as avgSalary from Employee group by DeptNo
having avgSalary=(
    select avg(Salary)as maxAvgSalary from Employee group by DeptNo order by maxAvgSalary desc
    limit 0,1
))as a
inner join Dept as b
on a.DeptNo=b.DeptNo;

/*方法2*/
select Employee.DeptNo,b.DName,avg(Salary)as avgSalary from Employee
inner join dept as b on Employee.DeptNo=b.DeptNo
group by Employee.DeptNo,b.DName
having avgSalary=(select avg(Salary)as maxAvgSalary from Employee group by DeptNo order by maxAvgSalary desc
                  limit 0,1);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

七、求平均薪水等級最低的部門的部門名稱

1、先求出各部門中最低平均薪水的等級
2、再求出各部門中平均薪水等級=最低平均薪水等級的部門編號
3、最後求出各部門中平均薪水等級=最低平均薪水等級的部門名稱

select a.DeptNo,c.DName,a.avgSalary,b.Grade from(select DeptNo,avg(Salary)as avgSalary from Employee group by DeptNo)as a
inner join salarygrade as b on a.avgSalary between b.Lowest and b.Higest
inner join Dept as c on a.DeptNo=c.DeptNo
group by DeptNo,b.Grade
having b.Grade=(select b.Grade from(select DeptNo,avg(Salary)as avgSalary from Employee group by DeptNo order by avgSalary asc limit 0,1)as a
                inner join salarygrade as b on a.avgSalary between b.Lowest and b.Higest)
order by avgSalary asc;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

八、求比普通員工的最高薪水還要高的經理姓名

1、先求出普通員工的最高薪水
2、在求出比普通員工的最高薪水還要高的經理姓名

select EmployeeName,Salary from Employee
where Job=‘Manager‘ and Salary>(select max(Salary)as maxWorkerSalary from Employee where Job=‘Worker‘);
  • 1
  • 2

九、取得薪水最高的前五名員工

1、limit 0,5,0表示從下標=0的數據開始取(第1條),5表示取5條數據

select EmployeeName,Salary from Employee
where Job=‘Worker‘
order by Salary desc
limit 0,5;
  • 1
  • 2
  • 3
  • 4

十、取得薪水最高的第六到第十名員工

1、limit 5,5,第一個5表示從下標=5的數據開始取(第6條),第二個5表示取5條數據

select EmployeeName,Salary from Employee
where Job=‘Worker‘
order by Salary desc
limit 5,5;
  • 1
  • 2
  • 3
  • 4

十一、取得最後入職的五名員工

1、可以根據時間來排序

select EmployeeName,Salary,CreateDate from Employee
order by CreateDate desc
limit 0,5;
  • 1
  • 2
  • 3

十二、取得每個薪水等級有多少名員工

1、先求每個員工的薪水等級
2、再求每個薪水等級有多少名員工

select Grade,count(*) from (select EmployeeName,Salary,b.Grade from Employee
                            inner join SalaryGrade as b
                            on Employee.Salary between b.Lowest and b.Highest)as a
group by Grade
order by Grade asc;
  • 1
  • 2
  • 3
  • 4
  • 5

十三、有三個表S(學生表)、C(課程表)、SC(學生選課表)

S(SNo, SName)代表(學號, 姓名)
C(CNo, CName, CTeacher)代表(課號, 課名, 老師)
SC(SNo, CNo, Score)代表(學號, 課號, 成績)
1、找出沒選過”張國榮”老師的所有學生姓名
1.1、找出選過”張國榮”老師的學生學號
1.2、找出沒選過”張國榮”老師的學生姓名

select SNo,SName from S
where SNo not in (select distinct SNo from SC
                  inner join C on SC.CNo=C.CNo and C.CTeacher=‘張國榮‘
                  where SNo is not null);
  • 1
  • 2
  • 3
  • 4

2、列出2門以上(含2門)不及格學生姓名及平均分
2.1、先找出不及格課程數>1的所有學生編號
2.2、再找出不及格課程數>1的所有學生姓名及平均分

select SC.SNo,S.SName,avg(Score) from SC
inner join S on SC.SNo=S.SNo
where SNo in(select SNo from SC where Score<60
             group by SNo
             having count(*)>1)
group by SC.SNo,S.SName;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3、既學過1號課程也學過2號課程的學生
3.1、先找出學過2號課程的學生編號集Set1
3.2、再找出學過1號課程的學生編號,這些學生編號必須也存在於Set1中

select SC.SNo,S.SName from SC 
inner join S on SC.SNo=S.SNo
where CNo=1 and SC.SNo in(select SNo from SC where CNo=2);
  • 1
  • 2
  • 3

十四、列出所有員工及其領導的名字

1、表可以自連接

select  Employee.EmployeeName,b.EmployeeName as LeaderName from Employee
left join Employee as b
on Employee.LeaderId=b.Id;
  • 1
  • 2
  • 3

十五、列出受雇日期早於其直接上級領導的所有員工編號、姓名

1、表可以自連接

select  Employee.EmployeeName,Employee.CreateDate,b.EmployeeName as LeaderName,b.CreateDate as LeaderCreateDate from Employee
left join Employee as b
on Employee.LeaderId=b.Id and Employee.CreateDate<b.CreateDate;
  • 1
  • 2
  • 3

十六、列出部門名稱和這些部門的員工信息,同時列出沒有員工的部門名稱

1、左外連接以左邊表中的數據為主

select Dept.DeptNo,Dept.DName,b.EmployeeName from Dept
left join Employee as b on Dept.DeptNo=b.DeptNo;
  • 1
  • 2

十七、列出至少有三個員工的所有部門名稱

1、group by和having聯合使用

select DeptNo,count(*)as employeeCount from Employee
group by DeptNo
having employeeCount>2;


十八、列出薪水比”賈躍亭”高的所有員工信息
1、先求出‘賈躍亭’的工資

select EmployeeName,EmployeeCode,Salary from employee
where Salary>(select Salary from Employee where EmployeeName=‘賈躍亭‘);
1
2
十九、列出所有Worker的姓名及其部門名稱、部門人數
1、先找出所有部門的名稱及其部門人數

select EmployeeName,b.DeptNo,b.DName,b.employeeCount from Employee
left join(select Employee.Id,Employee.DeptNo,b.DName,count(*)as employeeCount from Employee
inner join Dept as b on Employee.DeptNo=b.DeptNo
group by Employee.Id,Employee.DeptNo,b.DName)as b
on Employee.Id=b.Id
where Employee.Job=‘Worker‘;
1
2
3
4
5
6
二十、列出最低薪水>1500的各種工作及從事此工作的全部雇員人數
1、找出各種工作的全部雇員人數
2、找出最低薪水>1500的各種工作

select Employee.Job,min(Salary)as minSalary,b.employeeCount from Employee
inner join(select Job,count(*)as employeeCount from Employee group by Job)as b
on Employee.Job=b.Job
group by Employee.Job
having minSalary>1500;
1
2
3
4
5
二十一、列出在財務部工作的員工姓名,假定不知道財務部的編號
1、先找出財務部的編號

select * from Employee
where DeptNo=(select DeptNo from Dept where DName=‘財務部‘);
1
2
二十二、列出薪水高於公司平均薪水的所有員工,所在部門、薪水等級
1、先求出公司平均薪水
2、求出所有員工的所在部門、薪水等級

select Employee.EmployeeName,Employee.DeptNo,b.DName,Employee.Salary,c.Grade from Employee
inner join Dept as b on Employee.DeptNo=b.DeptNo
inner join SalaryGrade as c on employee.Salary between c.Lowest and c.Highest
where Employee.Salary>(select avg(Salary) from Employee);
1
2
3
4
二十三、列出與”安祿山”從事相同工作的所有員工及部門名稱
1、先找出‘安祿山’的工作崗位

select Employee.EmployeeName,Employee.Job,Employee.DeptNo,b.DName from Employee
inner join Dept as b on Employee.DeptNo=b.DeptNo
where Job=(select Job from Employee where EmployeeName=‘安祿山‘);
1
2
3
二十四、列出薪水等於財務部中員工薪水的其他員工的姓名和薪水
1、先找出財務部中所有員工的薪水

select EmployeeName,Salary from Employee
where Salary in(select Salary from Employee where DeptNo=‘101‘) and DeptNo != ‘101‘;
1
2
二十五、列出薪水大於財務部所有員工薪水的員工的姓名、薪水、部門名稱
1、找出財務部中的最高薪水

select Employee.EmployeeName,Employee.Salary,Employee.DeptNo,b.DName from Employee
inner join Dept as b on Employee.DeptNo=b.DeptNo
where Salary >(select max(Salary) from Employee where DeptNo=‘101‘);
1
2
3
二十六、列出每個部門的員工數量、平均薪水和平均服務期限
1、獲取系統當前時間now()
2、日期轉換為天數to_days()

select DeptNo,count(*),avg(Salary),avg(to_days(now())-to_days(CreateDate)) from Employee
group by DeptNo;
1
2
二十七、列出所有員工的姓名、部門名稱和工資
1、常見的內連接

select Employee.EmployeeName,Employee.DeptNo,b.DName,Employee.Salary from Employee
inner join Dept as b on Employee.DeptNo=b.DeptNo;
1
2
二十八、列出所有部門的詳細信息和人數
1、先求出所有部門的人數
2、IFNULL(expr1,expr2) 如果expr1是NULL,IFNULL()返回expr2,否則返回expr1

select Dept.DeptNo,DName,Location,ifnull(b.employeeCount,0) from Dept
left join (select DeptNo,count(*)as employeeCount from Employee group by DeptNo)as b
on Dept.DeptNo=b.DeptNo;
1
2
3
二十九、列出各種工作的最低工資及從事此工作的員工姓名
1、找出各工作的最低工資

select Employee.EmployeeName,Employee.Job,Employee.Salary from Employee
inner join (select Job,min(Salary)as minSalary from Employee group by Job)as b
on Employee.Job=b.Job and Employee.Salary=b.minSalary;
1
2
3
三十、列出各部門Manager的最低薪水
1、按照部門分類
2、工作崗位=’Manager’

select DeptNo,min(Salary) from Employee
where Job=‘Manager‘
group by DeptNo;
1
2
3
三十一、列出所有員工的年薪,按年薪升序排列
1、字段可以進行運算

select EmployeeName,(Salary+ifnull(Bonus,0))*12 as YearSalary from Employee
order by YearSalary asc;
1
2
三十二、求出員工領導的薪水超過7000的員工名稱和領導名稱
1、先把員工、員工領導、員工領導的薪水關聯起來

select Employee.EmployeeName,b.EmployeeName as LeaderName from Employee
inner join Empoloyee as b on Employee.LeaderId=b.Id
where b.Salary >7000;
1
2
3
三十三、求出部門名稱中帶”務”字符的工資合計和部門人數
1、求出所有部門的部門名稱、工資合計、部門人數

select Employee.DeptNo,b.DName,sum(Salary),count(*) from Employee
inner join Dept as b on Employee.DeptNo=b.DeptNo
where b.DName like ‘%務%‘
group by Employee.DeptNo,b.DName;
1
2
3
4
三十四、給任職超過1年的員工加薪10%
1、修改表中的信息

update Employee set Salary=Salary*1.1
where (to_days(now())-to_days(CreateDate))>365




MySql_34道經典Sql試題