|
| 1 | +drop database if exists hrs; |
| 2 | +create database hrs default charset utf8mb4; |
| 3 | + |
| 4 | +use hrs; |
| 5 | + |
| 6 | +create table tb_dept |
| 7 | +( |
| 8 | +dno int not null comment '编号', |
| 9 | +dname varchar(10) not null comment '名称', |
| 10 | +dloc varchar(20) not null comment '所在地', |
| 11 | +primary key (dno) |
| 12 | +); |
| 13 | + |
| 14 | +insert into tb_dept values |
| 15 | + (10, '会计部', '北京'), |
| 16 | + (20, '研发部', '成都'), |
| 17 | + (30, '销售部', '重庆'), |
| 18 | + (40, '运维部', '深圳'); |
| 19 | + |
| 20 | +create table tb_emp |
| 21 | +( |
| 22 | +eno int not null comment '员工编号', |
| 23 | +ename varchar(20) not null comment '员工姓名', |
| 24 | +job varchar(20) not null comment '员工职位', |
| 25 | +mgr int comment '主管编号', |
| 26 | +sal int not null comment '员工月薪', |
| 27 | +comm int comment '每月补贴', |
| 28 | +dno int comment '所在部门编号', |
| 29 | +primary key (eno), |
| 30 | +foreign key (dno) references tb_dept (dno) |
| 31 | +); |
| 32 | + |
| 33 | +-- alter table tb_emp add constraint pk_emp_eno primary key (eno); |
| 34 | +-- alter table tb_emp add constraint uk_emp_ename unique (ename); |
| 35 | +-- alter table tb_emp add constraint fk_emp_mgr foreign key (mgr) references tb_emp (eno); |
| 36 | +-- alter table tb_emp add constraint fk_emp_dno foreign key (dno) references tb_dept (dno); |
| 37 | + |
| 38 | +insert into tb_emp values |
| 39 | + (7800, '张三丰', '总裁', null, 9000, 1200, 20), |
| 40 | + (2056, '乔峰', '分析师', 7800, 5000, 1500, 20), |
| 41 | + (3088, '李莫愁', '设计师', 2056, 3500, 800, 20), |
| 42 | + (3211, '张无忌', '程序员', 2056, 3200, null, 20), |
| 43 | + (3233, '丘处机', '程序员', 2056, 3400, null, 20), |
| 44 | + (3251, '张翠山', '程序员', 2056, 4000, null, 20), |
| 45 | + (5566, '宋远桥', '会计师', 7800, 4000, 1000, 10), |
| 46 | + (5234, '郭靖', '出纳', 5566, 2000, null, 10), |
| 47 | + (3344, '黄蓉', '销售主管', 7800, 3000, 800, 30), |
| 48 | + (1359, '胡一刀', '销售员', 3344, 1800, 200, 30), |
| 49 | + (4466, '苗人凤', '销售员', 3344, 2500, null, 30), |
| 50 | + (3244, '欧阳锋', '程序员', 3088, 3200, null, 20), |
| 51 | + (3577, '杨过', '会计', 5566, 2200, null, 10), |
| 52 | + (3588, '朱九真', '会计', 5566, 2500, null, 10); |
| 53 | + |
| 54 | + |
| 55 | +-- 查询月薪最高的员工姓名和月薪 |
| 56 | +select ename, sal from tb_emp where sal=(select max(sal) from tb_emp); |
| 57 | + |
| 58 | +select ename, sal from tb_emp where sal>=all(select sal from tb_emp); |
| 59 | + |
| 60 | +-- 查询员工的姓名和年薪((月薪+补贴)*13) |
| 61 | +select ename, (sal+ifnull(comm,0))*13 as ann_sal from tb_emp order by ann_sal desc; |
| 62 | + |
| 63 | +-- 查询有员工的部门的编号和人数 |
| 64 | +select dno, count(*) as total from tb_emp group by dno; |
| 65 | + |
| 66 | +-- 查询所有部门的名称和人数 |
| 67 | +select dname, ifnull(total,0) as total from tb_dept left join |
| 68 | +(select dno, count(*) as total from tb_emp group by dno) tb_temp |
| 69 | +on tb_dept.dno=tb_temp.dno; |
| 70 | + |
| 71 | +-- 查询月薪最高的员工(Boss除外)的姓名和月薪 |
| 72 | +select ename, sal from tb_emp where sal=( |
| 73 | + select max(sal) from tb_emp where mgr is not null |
| 74 | +); |
| 75 | + |
| 76 | +-- 查询月薪排第2名的员工的姓名和月薪 |
| 77 | +select ename, sal from tb_emp where sal=( |
| 78 | + select distinct sal from tb_emp order by sal desc limit 1,1 |
| 79 | +); |
| 80 | + |
| 81 | +select ename, sal from tb_emp where sal=( |
| 82 | + select max(sal) from tb_emp where sal<(select max(sal) from tb_emp) |
| 83 | +); |
| 84 | + |
| 85 | +-- 查询月薪超过平均月薪的员工的姓名和月薪 |
| 86 | +select ename, sal from tb_emp where sal>(select avg(sal) from tb_emp); |
| 87 | + |
| 88 | +-- 查询月薪超过其所在部门平均月薪的员工的姓名、部门编号和月薪 |
| 89 | +select ename, t1.dno, sal from tb_emp t1 inner join |
| 90 | +(select dno, avg(sal) as avg_sal from tb_emp group by dno) t2 |
| 91 | +on t1.dno=t2.dno and sal>avg_sal; |
| 92 | + |
| 93 | +-- 查询部门中月薪最高的人姓名、月薪和所在部门名称 |
| 94 | +select ename, sal, dname |
| 95 | +from tb_emp t1, tb_dept t2, ( |
| 96 | + select dno, max(sal) as max_sal from tb_emp group by dno |
| 97 | +) t3 where t1.dno=t2.dno and t1.dno=t3.dno and sal=max_sal; |
| 98 | + |
| 99 | +-- 查询主管的姓名和职位 |
| 100 | +-- 提示:尽量少用in/not in运算,尽量少用distinct操作 |
| 101 | +-- 可以使用存在性判断(exists/not exists)替代集合运算和去重操作 |
| 102 | +select ename, job from tb_emp where eno in ( |
| 103 | + select distinct mgr from tb_emp where mgr is not null |
| 104 | +); |
| 105 | + |
| 106 | +select ename, job from tb_emp where eno=any( |
| 107 | + select distinct mgr from tb_emp where mgr is not null |
| 108 | +); |
| 109 | + |
| 110 | +select ename, job from tb_emp t1 where exists ( |
| 111 | + select 'x' from tb_emp t2 where t1.eno=t2.mgr |
| 112 | +); |
| 113 | + |
| 114 | +-- MySQL8有窗口函数:row_number() / rank() / dense_rank() |
| 115 | +-- 查询月薪排名4~6名的员工的排名、姓名和月薪 |
| 116 | +select ename, sal from tb_emp order by sal desc limit 3,3; |
| 117 | + |
| 118 | +select row_num, ename, sal from |
| 119 | +(select @a:=@a+1 as row_num, ename, sal |
| 120 | +from tb_emp, (select @a:=0) t1 order by sal desc) t2 |
| 121 | +where row_num between 4 and 6; |
| 122 | + |
| 123 | +-- 窗口函数不适合业务数据库,只适合做离线数据分析 |
| 124 | +select |
| 125 | + ename, sal, |
| 126 | + row_number() over (order by sal desc) as row_num, |
| 127 | + rank() over (order by sal desc) as ranking, |
| 128 | + dense_rank() over (order by sal desc) as dense_ranking |
| 129 | +from tb_emp limit 3 offset 3; |
| 130 | + |
| 131 | +select ename, sal, ranking from ( |
| 132 | + select ename, sal, dense_rank() over (order by sal desc) as ranking from tb_emp |
| 133 | +) tb_temp where ranking between 4 and 6; |
| 134 | + |
| 135 | +-- 窗口函数主要用于解决TopN查询问题 |
| 136 | +-- 查询每个部门月薪排前2名的员工姓名、月薪和部门编号 |
| 137 | +select ename, sal, dno from ( |
| 138 | + select ename, sal, dno, rank() over (partition by dno order by sal desc) as ranking |
| 139 | + from tb_emp |
| 140 | +) tb_temp where ranking<=2; |
| 141 | + |
| 142 | +select ename, sal, dno from tb_emp t1 |
| 143 | +where (select count(*) from tb_emp t2 where t1.dno=t2.dno and t2.sal>t1.sal)<2 |
| 144 | +order by dno asc, sal desc; |
0 commit comments