各个关键字的顺序:
select ..... from .... where .... group by .... having .... order by ..... limit ....;
①group by:分组查询
having:聚合函数的条件写在having后面
练习:
emp:EMPNO| ENAME | JOB | MGR| HIREdate| SAL| COMM | DEPTNO
dept:DEPTNO | DNAME | LOC
it_item: category_id | item_type| title| sell_point | price | num| barcode| image| status| priority | created_time|| modified_time | created_user
it_item_category:
id | parent_id| name| status| sort_order | is_parent| created_time | datetime| modified_time | datetime| created_user| modified_user
1. 查询每个部门的平均工资,要求平均工资大于2000
select deptno,avg(sal) a from emp group by deptno having a>2000;
2. 查询每个分类category_id的平均单价 要求平均单价低于100
select category_id,avg(price) a from it_item group by category_id having a<100;
3. 查询分类id为238,917的两个分类的平均单价
select category_id,avg(price) a from it_item where id in(238,917) group by category_id;
4. 查询emp表中每个部门的平均工资高于2000的部门编号,部门人数,平均工资,最后根据平均工资降序排序
select deptno,count(*),avg(sal) a from emp group by deptno having a>2000 order by a desc;
5. 查询emp表中工资在1000-3000之间的员工,每个部门的编号,工资总和,平均工资,过滤掉平均工资低于2000的部门,最后按照平均工资进行升序排序
select deptno,sum(sal),avg(sal) a from emp where sal between 1000 and 3000 group by deptno having a>=2000 order by a;
6. 查询每年入职的人数
select extract(year from hiredate) year,count(*) from emp group by year;
7.查询员工表中部门中最高的平均工资
select deptno,avg(sal) a from emp group by deptno order by a desc limit 0,1;
②子查询(嵌套查询)
1. 查询emp表中工资最高的员工信息
select * from emp where sal=(select max(sal) from emp);
2. 查询高于平均工资的员工信息
select * from emp where sal>(select avg(sal) from emp);
3. 查询工资高于20号部门最高工资的员工信息
select * from emp where sal>(select max(sal) from emp where deptno=20);
4. 查询和jones相同工作的其它员工信息
select * from emp where job=(select job from emp where ename='jones');
5. 查询工资最低的员工的同事们的信息(同事=同一个部门)
select * from emp where deptno=(select deptno from emp where sal=(select min(sal) from emp));
6. 查询最后入职的员工信息
select * from emp where hiredate=(select max(hiredate) from emp);
7. 查询king的部门编号和部门名称(需要用到dept表)
select e.deptno,d.dname from emp e join dept d on e.deptno=d.deptno where e.ename='king';
8. 查询有员工的部门信息
select * from dept where deptno in(select deptno from emp group by deptno having count(*)>0);
select d.*,count(e.empno) c from dept d join emp e on e.deptno=d.deptno group by deptno having c>0;
9. 查询平均工资最高的部门信息,需要考虑并列最高的问题)
select * from dept where deptno =(select deptno from emp group by deptno order by sum(sal) desc limit 0,1) group by deptno;
- 子查询总结:
1. 可以嵌套无数层
2. 子查询可写的位置:
1. 把子查询写在where或having的后面,当成查询条件的值
2. 写在创建表的时候
create table emp_20 as (select * from emp where deptno=20);
3. 写在from后面,当成一张虚拟的表 **必须有别名**
select ename from (select * from emp where deptno=20) newtable;
③关联查询:同时查询多张有关联关系的表
- 如果关联查询不写关联关系会得到两张表数据的乘积,这种乘积称为笛卡尔积。笛卡尔积是一种错误的查询结果会占用大量的内存,工作中切记不要出现。
练习:
1. 查询每一个员工的员工姓名和对应的部门名称
select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno;
2. 查询在new york工作的员工姓名
select d.loc,e.ename from dept d,emp e where e.deptno=d.deptno and d.loc='new york';
④等;值连接和内连接
- 等值连接和内连接查询到的是一样的结果,为两张表的交集数据
等值连接: select * from A,B where A.x=B.x and A.age=18;
内连接:select * from A [inner] join B on A.x=B.x where A.age=18;
- 案例:查询每一个员工的员工姓名和对应的部门名称
select e.ename,d.dname
from emp e join dept d
on e.deptno=d.deptno;
⑤外连接
- 外连接查询到的是一张表的全部数据和另外一张表的交集数据
- 格式: select * from A left/right [outer] join B on A.x=B.x where A.age=18;
1. 查询所有的部门名和其对应的员工名
select d.dname,e.ename
from emp e right join dept d
on e.deptno=d.deptno;
练习:
1.案例:查询emp表中,每个部门的平均工资高于2000的部门的编号,部门的人数,平均工资,最后根据平均工资进行升序排列。
select d.deptno,count(e.deptno),avg(e.sal) a from emp e join dept d group by e.deptno having a>2000 order by a;
2.案例:查询emp表中名字中不是以'K'开头的信息,每个部门的最低工资高于1000的部门的编号,工资总和,平均工资以及最低工资,最后根据平均工资进行升序排列。
select deptno,sum(sal),avg(sal) a,min(sal) m from emp where ename not like 'K%' group by deptno having m>1000 order by a;
3.案例:查询emp表中部门编号是10,30号部门的员工,每个职业的最高工资低于5000的职业的名称,人数,平均工资,最高工资,最后根据人数进行升序排列,如果人数一致,根据最高工资进行降序排列。
select job,count(*) c,max(sal) m from emp where deptno in(10,30) group by job having m<5000 order by c,m desc;
4.案例:查询emp表中,每个部门的编号,人数,工资总和,最高工资以及最低工资,过滤掉最高工资是5000的部门,根据部门的人数进行升序排列,如果人数一致,则根据最高工资进行降序排列。
select deptno,count(empno) c,sum(sal),max(sal) m,min(sal) from emp group by deptno having m!=5000 order by c,m desc;
5. 案例:查询emp表中工资在1000~3000之间的员工信息,每个部门的编号,工资总和,平均工资,过滤掉平均工资低于2000的部门,按照平均工资进行升序排列
select deptno,sum(sal),avg(sal) a from emp where sal between 1000 and 3000 group by deptno having a>=2000 order by a;
6. 案例:查询emp表中名字不是以‘S’开头,每个职位的名字,人数,工资总和,最高工资,过滤掉工资是3000的职位,根据人数进行升序排列,如果人数一致,根据工资总和进行降序排列。
select job,count(job) c,sum(sal),max(sal) m from emp where ename not like 'S%' and sal!=3000 group by job order by c,m desc;
7. 案例:查询emp表的信息,每个职位的名称,人数,平均工资,最低工资,过滤掉平均工资是3000的职位信息,根据人数进行降序排列,如果人数一致,根据平均工资进行升序排列
select job,count(*) c,avg(sal) a,min(sal) from emp group by job having a!=3000 order by c desc,a;
表emp:empno,ename,job,mgr,hiredate,sal,comm,deptno
表dept:deptno,dname,loc
1. 每个部门的人数,根据人数降序排序
select deptno,count(*) c from emp group by deptno order by c desc;
2. 每个部门中,每个主管的手下人数
select deptno,mgr,count(*) from emp group by deptno,mgr;
3. 每种工作的平均工资
select job,avg(sal) from emp group by job;
4. 每年的入职人数
select extract(year from hiredate) year,count(*) from emp group by year;
5. 少于等于3个人的部门信息
两次单表查询:select * from dept where deptno in(select deptno from emp group by deptno having count(*)<=3) ;
内连接:select d.* from dept d join emp e on d.deptno=e.deptno group by deptno having count(e.empno)<=3;
外连接:select d.* from dept d right join emp e on d.deptno=e.deptno group by deptno having count(e.empno)<=3;
6. 拿最低工资的员工信息
select * from emp where sal=(select min(sal) from emp);
select * from emp order by sal limit 0,1;
7. 只有一个下属的主管信息
select * from emp where empno in(select mgr from emp where mgr is not null group by mgr having count(*)=1);
8. 每月发工资最多的部门信息
select d.* from dept d join emp e on d.deptno=e.deptno group by e.deptno order by sum(sal) desc limit 0,1;
9. 下属最多的人,查询其个人信息
select * from emp where empno=(select mgr from emp group by mgr order by count(*) desc limit 0,1);
10. 拿最高工资员工的同事信息
select * from emp where deptno=(select deptno from emp order by sal desc limit 0,1);
11. 和最后入职的员工在同一部门的员工信息 实现流程和第十题一样
select * from emp where deptno=(select deptno from emp order by hiredate desc limit 0,1);
12. 查询平均工资高于20号平均工资的部门信息
select d.* from dept d join emp e on d.deptno=e.deptno group by deptno having avg(sal)>(select avg(sal) from emp where deptno=20 group by deptno);
13. 查询员工信息和员工对应的部门名称
select e.*,d.dname from emp e left join dept d on d.deptno=e.deptno;
14. 查询员工信息,部门名称,所在城市
select e.*,d.dname,d.loc from emp e left join dept d on d.deptno=e.deptno;
15. 查询Dallas市所有的员工信息
select * from emp e join dept d on e.deptno=d.deptno where d.loc='Dallas';
16. 计算每个城市的员工数量
select d.loc,count(e.empno) from dept d join emp e on d.deptno=e.deptno group by d.loc;
17. 查询员工信息和他的主管姓名
select e1.*,e2.ename from emp e1 join emp e2 on e1.mgr=e2.empno;
18. 员工信息,员工主管名字,部门名
select e1.*,e2.ename,d.dname from emp e1 join emp e2 on e1.mgr=e2.empno join dept d on e1.deptno=d.deptno;
19. 员工名和他所在部门名
select e.ename,d.dname from emp e join dept d on e.deptno=d.deptno;
20. 查询emp表中所有员工的姓名以及该员工上级领导的编号,姓名,职位,工资
select e1.ename,e1.mgr,e2.deptno,e2.ename,e2.job,e2.sal from emp e1 join emp e2 on e1.mgr=e2.empno;
21. 查询emp表中名字中没有字母'K'的所有员工的编号,姓名,职位以及所在部门的编号,名称,地址
select e.empno,e.ename,e.sal,d.deptno,d.dname,d.loc from emp e join dept d on e.deptno=d.deptno where e.ename not like '%K%';
22. 查询dept表中所有的部门的所有的信息,以及与之关联的emp表中员工的编号,姓名,职位,工资
select d.*,e.empno,e.ename,e.job,e.sal from dept d left join emp e on d.deptno=e.deptno;