1. 程式人生 > >MySQL練習2

MySQL練習2

來源網路,整理後分享

下圖是表結構:dept為部門表,grade為績效表, emp為僱員表,其中deptno欄位關聯dept表的deptno欄位


執行的sql語句如下:

DROP DATABASE IF EXISTS test;
CREATE DATABASE test;
use test;



create table dept (
deptno char(2) not null primary key,
dname varchar(15) not null,
loc varchar(15) not null
) default charset=utf8;

insert into dept (deptno, dname, loc) values('10', 'accounting' ,'new york');
insert into dept (deptno, dname, loc) values('20', 'research','dallas');
insert into dept (deptno, dname, loc) values('30', 'sales' ,'chicago');
insert into dept (deptno, dname, loc) values('40', 'operations' ,'boston');

create table grade (
grade int(1) not null primary key,
losal int(4) not null,
hisal int(4) not null
) default charset=utf8;

insert into grade (grade, losal, hisal) values (1, 700, 1200);
insert into grade (grade, losal, hisal) values (2, 1201, 1400);
insert into grade (grade, losal, hisal) values (3, 1401, 2000);
insert into grade (grade, losal, hisal) values (4, 2001, 3000);
insert into grade (grade, losal, hisal) values (5, 3001, 9900);

CREATE TABLE emp (
empno char(4) not null primary key,
ename varchar(10) not null,
job varchar(15) not null,
mgr char(4),
hiredate date not null,
sal int(4) not null,
comm int(4),
deptno char(2),
foreign key(deptno) references dept(deptno)
)default charset=utf8;

insert into emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) values('7369', 'smith', 'clerk', '7902', '1980-12-17', 800, null, 

'20');
insert into emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) values('7499', 'allen', 'salesman', '7698', '1981-02-20', 1600, 300, 

'30');
insert into emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) values('7521', 'ward', 'salesman', '7902', '1981-02-22', 1250, 500, 

'30');
insert into emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) values('7566', 'jones', 'manager', '7839', '1981-04-02', 2975, null, 

'20');
insert into emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) values('7654', 'martin', 'salesman', '7698', '1981-09-28', 1250, 

1400, '30');
insert into emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) values('7698', 'blake', 'manager', '7839', '1981-05-01', 2850,
null,'30');
insert into emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) values('7782', 'clark', 'manager', '7839', '1981-06-09', 2450, 
null,'10');
insert into emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) values('7788', 'scott', 'analyst', '7566', '1987-04-19', 3000, null, 

'20');
insert into emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) values('7839', 'king','president', null, '1981-11-17', 5000, 

null,'10');
insert into emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) values('7844', 'turner', 'salesman', '7698', '1981-09-08', 1500, 0, 

'30');
insert into emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) values('7876', 'adams', 'clerk', '7788', '1981-05-23', 1100, 
null,'20');
insert into emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) values('7900', 'james', 'clerk', '7698', '1981-12-03', 950, null, 

'30');
insert into emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) values('7902', 'ford','analyst', '7566', '1981-12-03', 3000, 

null,'20');
insert into emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) values('7934', 'miller', 'clerk', '7782', '1982-01-23', 1300, null, 

'10');

練習題目及參考答案:

1、取得每個部門中的最高薪水的人員名稱。
   select b.ename, b.sal, b.deptno from (select deptno, max(sal) as sal from emp  group by deptno) a, emp b where a.deptno = b.deptno and a.sal = b.sal;
2、哪些人的薪水在部門的平均薪水之上, 列出姓名,薪金,部門號。
 select b.ename, b.sal, b.deptno from (select deptno, avg(sal)  as sal from emp  group by deptno) a, emp b where a.deptno = b.deptno and b.sal > a.sal;
3、取得部門平均薪水的等級, 列出部門,等級:
    select a.deptno, b.grade from  (select deptno, avg(sal) as sal from emp group by deptno) a, grade b where a.sal between b.losal and b.hisal;
4、不準用分組函式(Max),取得最高薪水。
    select * from emp order by sal desc limit 1;
5、取得平均薪水最高的部門的部門編號
   select deptno, avg(sal) as sal from emp group by deptno order by sal desc limit 1;
6、取得平均薪水最高的部門的部門名稱。
   select a.deptno, avg(a.sal) as sal, b.dname from emp a, dept b where a.deptno = b.deptno group by a.deptno order by sal desc limit 1;
7、求平均薪水的等級最低的部門的部門名稱。
    select a.deptno, c.dname, b.grade from (select deptno, avg(sal) as avg_sal from emp group by deptno) a, grade b, dept c where a.deptno = c.deptno and a.avg_sal between b.losal and b.hisal order by b.grade limit 1; 
8、取得比普通員工(員工程式碼沒有在mgr欄位上出現的)的最高薪水還要高的領導人姓名。
   1.員工編號,薪水錶
       // select empno from emp where empno not in (select distinct mgr from emp where mgr is not null);
       select distinct e1.empno, e1.sal from emp e1 left join emp e2 on e1.empno = e2.mgr where e2.empno is null;
   2.員工最高薪水值
       select max(e1.sal) from emp e1 left join emp e2 on e1.empno = e2.mgr where e2.empno is null;
   3.領導表
       select distinct mgr from emp where mgr is not null
   4.聯結上述表
       select em.ename from (select distinct mgr from emp where mgr is not null) as ma, emp em where ma.mgr = em.empno and em.sal > 


(select max(e1.sal) from emp e1 left join emp e2 on e1.empno = e2.mgr where e2.empno is null);
9、取得薪水最高的前五名員工。
    select * from emp order by sal desc limit 5;
10、取得薪水最高的第六到第十名員工。
    select * from emp order by sal desc limit 5, 5;
11、取得最後入職的5名員工。
    select * from emp order by hiredate desc limit 5;
12、取得每個薪水等級有多少員工
    select gr.grade, count(em.empno) from emp em, grade gr where em.sal between gr.losal and gr.hisal group by gr.grade;
13、列出所有員工及領導的姓名
    select ename from emp;
14、列出受僱日期早於其直接上級的所有員工的編號,姓名,部門名稱
    select em1.empno, em1.ename, em1.deptno from emp em1, emp em2 where em1.mgr = em2.empno and em1.hiredate < em2.hiredate;
15、列出部門名稱和這些部門的員工資訊(員工編號,員工姓名),同時列出那些沒有員工的部門.
    select de.dname, em.empno, em.ename from dept de left join emp em on de.deptno = em.deptno;
16、列出至少有5個員工的所有部門編號
    select deptno from emp group by deptno having count(empno) >= 5;
17、列出薪金比"SMITH"多的所有員工資訊.
    select * from emp where sal > (select sal from emp where ename ='smith');
18、列出所有"CLERK"(辦事員)的姓名及其部門名稱,部門的人數.
    1. 各部門的人數表
    select deptno, count(empno) from emp group by deptno
    2. 與辦事員的姓名,部門名稱
    select em.ename, de.dname from dept de, emp em where de.deptno = em.deptno and em.job = 'clerk';
    3. 聯立上述兩張表
    select em.ename, de.dname, t.c from dept de, emp em, (select deptno, count(empno) as c from emp group by deptno) t where de.deptno = em.deptno and t.deptno = de.deptno and em.job = 'clerk';
19、列出最低薪金大於1500的各種工作及從事此工作的全部僱員人數.
    select job, count(empno) from emp group by job having min(sal) > 1500;
20、列出在部門"SALES"<銷售部>工作的員工的姓名,假定不知道銷售部的部門編號.
    select em.ename from dept de, emp em where de.deptno = em.deptno and de.dname = 'sales';
21、列出薪金高於公司平均薪金的所有員工,所在部門,編號上級領導編號,僱員的工資等級.
    select em.empno, em.ename, em.deptno, em.mgr, gr.grade from emp em, grade gr where em.sal > (select avg(sal) from emp) and em.sal between gr.losal and gr.hisal;
22、列出與"SCOTT"從事相同工作的其他員工及部門名稱.
    select em.empno, em.ename, de.dname from dept de, emp em where de.deptno = em.deptno and em.job = (select job from emp where ename='scott') and em.ename != 'scott';
23、列出薪金等於部門30中員工的薪金的其他員工的姓名和薪金.
    select ename, sal from emp where deptno != '30' and sal = any(select sal from emp where deptno='30');-- 可以用in
24、列出薪金高於在部門30工作的所有員工的薪金的員工姓名和薪金.部門名稱.
    select em.ename, em.sal, de.dname from emp em, dept de where em.deptno = de.deptno and em.deptno != '30' and em.sal > ALL(select sal from emp where deptno='30');-- 可以用max
25、列出在每個部門工作的員工數量,平均工資和平均服務期限.
    select deptno, count(empno), avg(sal), avg(year(now()) - year(hiredate)) from emp group by deptno;
26、列出所有員工的姓名、部門名稱和工資。
select em.ename, de.dname,  em.sal from emp em, dept de where em.deptno = de.deptno;
27、列出所有部門的詳細資訊和人數(有些部門沒有員工)
    select d.deptno, d.dname, t.c from dept d left join (select de.deptno as no , count(em.empno) as c from emp em, dept de where em.deptno = de.deptno group by de.deptno) t on t.no = d.deptno;
28、列出各種工作的最低工資及從事此工作的僱員姓名
    select em1.ename, em1.sal from emp em1, (select job, min(sal) as min_sal from emp group by job) em2 where em1.job = em2.job and em1.sal = em2.min_sal;
29、列出各個部門的job為MANAGER(領導)的最低薪金
    select min(sal) from emp where job='manager' group by deptno;
30、列出所有員工的年工資,按年薪從低到高排序((sal + comm) * 12)
    select ename, (sal  + IFNULL(comm, 0)) * 12  as year_sal from emp order by year_sal;
31、求出領導的薪水超過3000的員工名稱與領導名稱
    select e1.ename, e1.sal, e2.ename, e2.sal from emp e1, emp e2 where e1.mgr = e2.empno and e2.sal > 3000;
32、求出部門名稱中,帶'S'字元的部門員工的工資合計、部門人數.
    select em.deptno, sum(em.sal), count(em.empno) from emp em, dept de where em.deptno = de.deptno and de.dname like '%s%' group by em.deptno; -- 或者使用 de.dname regexp 's' 
33、給任職日期超過30年的員工加薪10%.
    update emp set sal = sal * 1.1 where year(now()) - year(hiredate) > 30;