练习
1. 案例:查询没有上级领导的员工的编号,姓名,工资select empno,ename,salfrom empwhere mgr is null;2. 案例:查询emp表中没有奖金的员工的姓名,职位,工资,以及奖金select ename,job,sal,commfrom empwhere comm=0 or comm is null;3. 案例:查询emp表中含有奖金的员工的编号,姓名,职位,以及奖金select empno,ename,job,commfrom empwhere comm>0;4. 案例:查询含有上级领导的员工的姓名,工资以及上级领导的编号select ename,sal,mgrfrom empwhere mgr is not null;5. 案例:查询emp表中名字以‘S’开头的所有员工的姓名select enamefrom empwhere ename like 's%';6. 案例:查询emp表中名字的最后一个字符是'S'的员工的姓名select enamefrom empwhere ename like '%s';7. 案例:查询倒数的第2个字符是‘E’的员工的姓名select enamefrom empwhere ename like '%e_';8. 案例:查询emp表中员工的倒数第3个字符是‘N’的员工姓名select enamefrom empwhere ename like '%n__';9. 案例:查询emp表中员工的名字中包含‘A’的员工的姓名select enamefrom empwhere ename like '%a%';10. 案例:查询emp表中名字不是以'K'开头的员工的所有信息select *from empwhere ename not like 'k%';11. 案例:查询emp表中名字中不包含‘A’的所有员工的信息select *from empwhere ename not like '%a%';12. 案例:做文员的员工人数(job 中 含有 CLERK 的)select count(*)from empwhere job='clerk';13. 案例:销售人员 job: SALESMAN 的最高薪水select max(sal)from empwhere job='salesman';14. 案例:最早和最晚入职时间select min(hiredate),max(hiredate)from emp;15. 案例:查询类别 163的商品总库存量select sum(num)from t_itemwhere category_id=163;16. 案例:查询 类别 163 的商品select *from t_itemwhere category_id = 163;17. 案例:查询商品价格不大于100的商品名称列表select titlefrom t_itemwhere price <= 100;18. 案例:查询品牌是联想,且价格在40000以上的商品名称和价格select title,pricefrom t_itemwhere title like '%联想%' and price>40000;19. 案例:查询品牌是三木,或价格在50以下的商品名称和价格select title,pricefrom t_itemwhere title like '%三木%' or price<50;20. 案例:查询品牌是三木、广博、齐心的商品名称和价格select title,pricefrom t_itemwhere title like '%三木%' or title like '%广博%' or title like '%齐心%';21. 案例:查询品牌不是联想、戴尔的商品名称和价格select title,pricefrom t_itemwhere title not like '%联想%' and title not like '%戴尔%';22. 案例:查找品牌是联想且价格大于10000的名称select titlefrom t_itemwhere title like '%联想%' and price>10000;23. 案例:查询联想或戴尔的电脑名称列表select titlefrom t_itemwhere title like '%联想%' or title like '%戴尔%';24. 案例:查询卖点含有'赠'产品名称select titlefrom t_itemwhere sell_point like '%赠%';25. 案例:查询emp表中员工的编号,姓名,职位,工资,并且工资在1000~2000之间。select empno,ename,job,salfrom empwhere sal between 1000 and 2000;26. 案例:查询emp表中员工在10号部门,并且含有上级领导的员工的姓名,职位,上级领导编号以及所属部门的编号select ename,job,mgr,deptnofrom empwhere deptno=10 and mgr is not null;27. 案例:查询emp表中名字中包含'E',并且职位不是MANAGER的员工的编号,姓名,职位,以及工资。select empno,ename,job,sal from empwhere enamelike '%e%' and job!='manager';28. 案例:查询emp表中10号部门或者20号部门中员工的编号,姓名,所属部门的编号select empno,ename,deptnofrom empwhere deptno in(10,20);29. 案例:查询emp表中没有奖金或者名字的倒数第2个字母不是T的员工的编号,姓名,职位以及奖金select empno,eanme,job,commfrom empwhere comm=0 or comm is null or ename not like '%t_';30. 案例:查询工资高于3000或者部门编号是30的员工的姓名,职位,工资,入职时间以及所属部门的编号select ename,job,sal,hiredate,deptnofrom empwhere sal>3000 or deptno=30;31. 案例:查询不是30号部门的员工的所有信息select *from empwhere deptno!=30;32. 案例:查询奖金不为空的员工的所有信息select *from empwhere comm is not null;33. 案例:查询emp表中所有员工的编号,姓名,职位,根据员工的编号进行降序排列select empno,ename,jobfrom emporder by empno desc;34. 案例:查询emp表中部门编号是10号或者30号中,所有员工姓名,职务,工资,根据工资进行升序排列select ename,job,salfrom empwhere deptno in(10,30)order by sal;35. 案例:查询emp表中所有的数据,然后根据部门的编号进行升序排列,如果部门编号一致,根据员工的编号进行降序排列select *from emporder by deptno,empno desc;36. 案例:查询emp表中工资高于1000或者没有上级领导的员工的编号,姓名,工资,所属部门的编号,以及上级领导的编号,根据部门编号进行降序排列,如果部门编号一致根据工资进行升序排列。select empno,ename,sal,deptno,mgrfrom empwhere sal>1000 or mgr is nullorder by deptno desc,sal;37. 案例:查询emp表中名字中不包含S的员工的编号,姓名,工资,奖金,根据工资进行升序排列,如果工资一致,根据编号进行降序排列select empno,ename,sal,commfrom empwhere ename not like '%s%'order by sal,empno desc;38. 案例:统计emp表中员工的总数量select count(*)from emp;39. 案例:统计emp表中获得奖金的员工的数量select count(*)from empwhere comm>0;40. 案例:求出emp表中所有的工资累加之和select sum(sal)from emp;41. 案例:求出emp表中所有的奖金累加之和select sum(comm)from emp;42. 案例:求出emp表中员工的平均工资select avg(sal)from emp;43. 案例:求出emp表中员工的平均奖金select avg(comm)from emp;44. 案例:求出emp表中员工的最高工资select max(sal)from emp;45. 案例:求出emp表中员工编号的最大值select max(empno)from emp;46. 案例:查询emp表中员工的最低工资。select min(sal)from emp;47. 案例:查询emp表中员工的人数,工资的总和,平均工资,奖金的最大值,奖金的最小值,并且对返回的列起别名。select count(*) 总人数,sum(sal) 工资总和,avg(sal) 平均工资,max(comm) 最高奖金, min(comm) 最低奖金from emp;
数学相关函数
1. 向下取整 floor(num)select floor(3.8);2. 四舍五入 round(num)select round(23.8);3. 四舍五入 round(num,m) m代表小数位数select round(23.879,2);4. 非四舍五入 truncate(num,m) m代表小数位数select truncate(23.879,2);5. 随机数 rand() 0-1随机数select rand();6. 3-5的随机整数 3,4,5 0-2+2select floor(rand()*3+3);
分组查询
格式:group by 分组字段名
每个或每种什么,就以什么进行分组查询
1. 查询每个部门的平均工资select deptno,avg(sal)from empgroup by deptno;2. 查询每种职业的最高工资select job,max(sal)from empgroup by job;3. 查询每个部门的人数select deptno,count(*)from empgroup by deptno;4. 查询工资大于1000的员工中每个部门的最高工资select deptno,max(sal)from empwhere sal>1000group by deptno;5. 查询每个领导的手下人数select mgr,count(*)from empwhere mgr is not nullgroup by mgr;
多字段分组在group by后面写多个字段名
1. 查询每个部门,每种职业的平均工资select deptno,job,avg(sal)from empgroup by deptno,job;2. 查询emp表中每个部门的编号、人数、工资总和、根据人数进行升序排序,如果人数一致根据工资总和降序排序select deptno,count(*),sum(sal)from empgroup by deptnoorder by count(*),sum(sal) desc;select deptno,count(*) c,sum(sal) sfrom empgroup by deptnoorder by c,s desc;3. 查询工资在1000~3000之间的员工信息,每个部门的编号,平均工资,最低工资,最高工资,根据平均工资进行升序排序select deptno,avg(sal) a,min(sal),max(sal)from empwhere sal between 1000 and 3000group by deptnoorder by a;4. 查询有上级领导的员工,每个职业的人数,工资总和,平均工资,根据人数进行降序排序,如果人数一致则根据平均工资进行升序排序select job,count(*) c,sum(sal),avg(sal) afrom empwhere mgr is not nullgroup by joborder by c desc,a;
having
where 后面只能写普通字段的条件,不能写聚合函数的条件 把聚合函数的条件写在having后面
各个关键字的顺序select .....from ....where ....group by ....having ....order by .....limit ....;
1. 查询每个部门的平均工资,要求平均工资大于2000select deptno,avg(sal) afrom empwhere a>2000group by deptno;select deptno,avg(sal) afrom empgroup by deptnohaving a>2000;2. 查询每个分类category_id的平均单价 要求平均单价低于100select category_id,avg(price) afrom t_itemgroup by category_idhaving a<100;3. 查询分类id为238,917的两个分类的平均单价select category_id,avg(price)from t_itemwhere category_id in(238,917)group by category_id;4. 查询emp表中每个部门的平均工资高于2000的部门编号,部门人数,平均工资,最后根据平均工资降序排序select deptno,count(*),avg(sal) afrom empgroup by deptnohaving a>2000order by a desc;5. 查询emp表中工资在1000-3000之间的员工,每个部门的编号,工资总和,平均工资,过滤掉平均工资低于2000的部门,最后按照平均工资进行升序排序select deptno,sum(sal),avg(sal) afrom empwhere sal between 1000 and 3000group by deptnohaving a>=2000order by a;
提高题
1. 查询每年入职的人数select extract(year from hiredate) year,count(*)from empgroup by year;2. 查询员工表中最高的平均工资select avg(sal) afrom empgroup by deptnoorder by a desclimit 0,1;
子查询(嵌套查询)
3. 查询emp表中工资最高的员工信息select max(sal)from emp; // 5000select *from empwhere sal=(select max(sal)from emp);4. 查询高于平均工资的员工信息select avg(sal)from emp;select *from empwhere sal>(select avg(sal)from emp);5. 查询工资高于20号部门最高工资的员工信息select *from empwhere sal>(select max(sal)from empwhere deptno=20);6. 查询和jones相同工作的其它员工信息select jobfrom empwhere ename='jones';select *from empwhere job=(select jobfrom empwhere ename='jones') and ename!='jones';7. 查询工资最低的员工的同事们的信息(同事=同一个部门)1. 得到最低工资select min(sal)from emp;2. 通过最低工资找到部门编号select deptnofrom empwhere sal=(select min(sal)from emp);3. 通过部门编号查询该部门的人,还要去掉工资最低的select *from empwhere deptno in(select deptnofrom empwhere sal=(select min(sal)from emp)) and sal != (select min(sal)from emp);8. 查询最后入职的员工信息select max(hiredate)from emp;select *from empwhere hiredate=(select max(hiredate)from emp);9. 查询king的部门编号和部门名称(需要用到dept表)select deptnofrom empwhere ename='king';select dnamefrom deptwhere deptno=(select deptnofrom empwhere ename='king');10. 查询有员工的部门信息(想办法过滤掉40号部门,因为它没员工)select distinct deptnofrom emp;select *from deptwhere deptno in(select distinct deptnofrom emp);11. 查询平均工资最高的部门信息(难度最高)需要考虑并列最高的问题(1). 得到最高的平均工资select avg(sal) afrom empgroup by deptnoorder by a desclimit 0,1;(2). 通过最高平均工资查部门编号select deptnofrom empgroup by deptnohaving avg(sal)=(select avg(sal) afrom empgroup by deptnoorder by a desclimit 0,1);(3). 通过部门编号查部门信息select *from deptwhere deptno in(上面一坨);
- 子查询总结:
- 可以嵌套无数层
- 子查询可写的位置:
- 把子查询写在where或having的后面,当成查询条件的值
- 写在创建表的时候
create table emp_20 as (select * from emp where deptno=20); - 写在from后面,当成一张虚拟的表 必须有别名
select ename from (select * from emp where deptno=20) newtable;
关联查询
- 同时查询多张表的数据的查询方式称为关联查询
- 如果关联查询不写关联关系会得到两张表数据的乘积,这种乘积称为笛卡尔积。
笛卡尔积是一种错误的查询结果会占用大量的内存,工作中切记不要出现。
1. 查询每一个员工的员工姓名和对应的部门名称select e.ename,d.dnamefrom emp e,dept dwhere e.deptno=d.deptno;2. 查询在new york工作的员工姓名select e.enamefrom emp e,dept dwhere e.deptno=d.deptno and d.loc='new york';
等值连接和内连接
等值连接和内连接查询到的是一样的结果,为两张表的交集数据
1. 等值连接select *from A,Bwhere A.x=B.x and A.age=18;2. 内连接select *from A[inner] join B on A.x=B.xwhere A.age=18;
案例:查询每一个员工的员工姓名和对应的部门名称select e.ename,d.dnamefrom emp ejoin dept d on e.deptno=d.deptno;
外连接
外连接查询到的是一张表的全部数据和另外一张表的交集数据
格式select *from Aleft/right [outer] join B on A.x=B.xwhere A.age=18;
查询所有的部门名和其对应的员工名select d.dname,e.enamefrom emp eright join dept d on e.deptno=d.deptno;
关联查询总结
- 查询方式有三种:等值连接、内连接、外连接
- 如果查询的数据是两张表的交集数据使用等值或内连接(推荐)
- 如果查询的数据是一张表的全部数据和另外一张表的交集数据使用外连接
练习
1. 每个部门的人数,根据人数降序排序select deptno,count(*) cfrom empgroup by deptnoorder by c desc;2. 每个部门中,每个主管的手下人数select deptno,mgr,count(*)from empwhere mgr is not nullgroup by deptno,mgr;3. 每种工作的平均工资select job,avg(sal)from empgroup by job;4. 每年的入职人数select extract(year from hiredate) year,count(*)from empgroup by year;5. 少于等于3个人的部门信息select d.*from emp eright join dept d on e.deptno=d.deptnogroup by deptnohaving count(e.ename)<=3;6. 拿最低工资的员工信息select * from empwhere sal=(select min(sal)from emp);7. 只有一个下属的主管信息select mgrfrom empwhere mgr is not nullgroup by mgrhaving count(*)=1;select *from empwhere empno in(select mgrfrom empwhere mgr is not nullgroup by mgrhaving count(*)=1);8. 每月发工资最多的部门信息(1).得到最高的工资总和select sum(sal) sfrom empgroup by deptnoorder by s desclimit 0,1;(2).通过工资总和查部门的编号select deptnofrom empgroup by deptnohaving sum(sal)=(select sum(sal) sfrom empgroup by deptnoorder by s desclimit 0,1);(3).通过部门编号查部门信息select *from deptwhere deptno in (上面一坨);9. 下属最多的人,查询其个人信息(1).得到下属最多的人数select count(*) cfrom empgroup by mgrorder by c desclimit 0,1;(2).通过人数找mgrselect mgrfrom empgroup by mgrhaving count(*)=(select count(*) cfrom empgroup by mgrorder by c desclimit 0,1);(3).通过mgr找个人信息select *from empwhere empno in(上面一坨);10. 拿最高工资员工的同事信息select *from empwhere deptno = (select deptnofrom empwhere sal=(select max(sal)from emp)) and sal !=(select max(sal)from emp);11. 和最后入职的员工在同一部门的员工信息 实现流程和第十题一样select max(hiredate)from emp;select deptnofrom empwhere hiredate=(select max(hiredate)from emp);select *from empwhere deptno=(select deptnofrom empwhere hiredate=(select max(hiredate) from emp)) and hiredate!=(select max(hiredate)from emp);12. 查询平均工资高于20号平均工资的部门信息select avg(sal)from empwhere deptno=20;select deptnofrom empgroup by deptnohaving avg(sal)>(select avg(sal)from empwhere deptno=20);select *from deptwhere deptno in(select deptnofrom empgroup by deptnohaving avg(sal)>(select avg(sal)from empwhere deptno=20));13. 查询员工信息和员工对应的部门名称select e.*,d.dnamefrom emp ejoin dept d on e.deptno=d.deptno;14. 查询员工信息,部门名称,所在城市select e.*,d.dname,d.locfrom emp ejoin dept d on e.deptno=d.deptno;15. 查询Dallas市所有的员工信息select e.*from emp ejoin dept don e.deptno=d.deptnowhere d.loc='dallas';16. 计算每个城市的员工数量select d.loc,count(e.empno)from emp eright join dept d on e.deptno=d.deptnogroup by d.loc;17. 查询员工信息和他的主管姓名 凡是自关联 把一张表当成两张表select e.ename,m.enamefrom emp ejoin emp m on e.mgr = m.empno;18. 员工信息,员工主管名字,部门名select e.ename,m.ename,d.dnamefrom emp ejoin emp m on e.mgr = m.empnojoin dept d on e.deptno=d.deptno;19. 员工名和他所在部门名select e.ename,d.dnamefrom emp ejoin dept d on e.deptno=d.deptno;20. 案例:查询emp表中所有员工的姓名以及该员工上级领导的编号,姓名,职位,工资select e.ename,m.empno,m.ename,m.job,m.salfrom emp eleft join emp m on e.mgr=m.empno;21. 案例:查询emp表中名字中没有字母'K'的所有员工的编号,姓名,职位以及所在部门的编号,名称,地址select e.empno,e.ename,e.job,d.deptno,d.dname,d.locfrom emp eleft join dept d on e.deptno=d.deptnowhere e.ename not like '%k%';22. 案例:查询dept表中所有的部门的所有的信息,以及与之关联的emp表中员工的编号,姓名,职位,工资select d.*,e.empno,e.ename,e.job,e.salfrom emp eright join dept d on e.deptno=d.deptno;
