练习

  1. 1. 案例:查询没有上级领导的员工的编号,姓名,工资
  2. select empno,ename,sal
  3. from emp
  4. where mgr is null;
  5. 2. 案例:查询emp表中没有奖金的员工的姓名,职位,工资,以及奖金
  6. select ename,job,sal,comm
  7. from emp
  8. where comm=0 or comm is null;
  9. 3. 案例:查询emp表中含有奖金的员工的编号,姓名,职位,以及奖金
  10. select empno,ename,job,comm
  11. from emp
  12. where comm>0;
  13. 4. 案例:查询含有上级领导的员工的姓名,工资以及上级领导的编号
  14. select ename,sal,mgr
  15. from emp
  16. where mgr is not null;
  17. 5. 案例:查询emp表中名字以‘S’开头的所有员工的姓名
  18. select ename
  19. from emp
  20. where ename like 's%';
  21. 6. 案例:查询emp表中名字的最后一个字符是'S'的员工的姓名
  22. select ename
  23. from emp
  24. where ename like '%s';
  25. 7. 案例:查询倒数的第2个字符是‘E’的员工的姓名
  26. select ename
  27. from emp
  28. where ename like '%e_';
  29. 8. 案例:查询emp表中员工的倒数第3个字符是‘N’的员工姓名
  30. select ename
  31. from emp
  32. where ename like '%n__';
  33. 9. 案例:查询emp表中员工的名字中包含‘A’的员工的姓名
  34. select ename
  35. from emp
  36. where ename like '%a%';
  37. 10. 案例:查询emp表中名字不是以'K'开头的员工的所有信息
  38. select *
  39. from emp
  40. where ename not like 'k%';
  41. 11. 案例:查询emp表中名字中不包含‘A’的所有员工的信息
  42. select *
  43. from emp
  44. where ename not like '%a%';
  45. 12. 案例:做文员的员工人数(job 含有 CLERK 的)
  46. select count(*)
  47. from emp
  48. where job='clerk';
  49. 13. 案例:销售人员 job: SALESMAN 的最高薪水
  50. select max(sal)
  51. from emp
  52. where job='salesman';
  53. 14. 案例:最早和最晚入职时间
  54. select min(hiredate),max(hiredate)
  55. from emp;
  56. 15. 案例:查询类别 163的商品总库存量
  57. select sum(num)
  58. from t_item
  59. where category_id=163;
  60. 16. 案例:查询 类别 163 的商品
  61. select *
  62. from t_item
  63. where category_id = 163;
  64. 17. 案例:查询商品价格不大于100的商品名称列表
  65. select title
  66. from t_item
  67. where price <= 100;
  68. 18. 案例:查询品牌是联想,且价格在40000以上的商品名称和价格
  69. select title,price
  70. from t_item
  71. where title like '%联想%' and price>40000;
  72. 19. 案例:查询品牌是三木,或价格在50以下的商品名称和价格
  73. select title,price
  74. from t_item
  75. where title like '%三木%' or price<50;
  76. 20. 案例:查询品牌是三木、广博、齐心的商品名称和价格
  77. select title,price
  78. from t_item
  79. where title like '%三木%' or title like '%广博%' or title like '%齐心%';
  80. 21. 案例:查询品牌不是联想、戴尔的商品名称和价格
  81. select title,price
  82. from t_item
  83. where title not like '%联想%' and title not like '%戴尔%';
  84. 22. 案例:查找品牌是联想且价格大于10000的名称
  85. select title
  86. from t_item
  87. where title like '%联想%' and price>10000;
  88. 23. 案例:查询联想或戴尔的电脑名称列表
  89. select title
  90. from t_item
  91. where title like '%联想%' or title like '%戴尔%';
  92. 24. 案例:查询卖点含有'赠'产品名称
  93. select title
  94. from t_item
  95. where sell_point like '%赠%';
  96. 25. 案例:查询emp表中员工的编号,姓名,职位,工资,并且工资在1000~2000之间。
  97. select empno,ename,job,sal
  98. from emp
  99. where sal between 1000 and 2000;
  100. 26. 案例:查询emp表中员工在10号部门,并且含有上级领导的员工的姓名,职位,上级领导编号以及所属部门的编号
  101. select ename,job,mgr,deptno
  102. from emp
  103. where deptno=10 and mgr is not null;
  104. 27. 案例:查询emp表中名字中包含'E',并且职位不是MANAGER的员工的编号,姓名,职位,以及工资。
  105. select empno,ename,job,sal from emp
  106. where ename
  107. like '%e%' and job!='manager';
  108. 28. 案例:查询emp表中10号部门或者20号部门中员工的编号,姓名,所属部门的编号
  109. select empno,ename,deptno
  110. from emp
  111. where deptno in(10,20);
  112. 29. 案例:查询emp表中没有奖金或者名字的倒数第2个字母不是T的员工的编号,姓名,职位以及奖金
  113. select empno,eanme,job,comm
  114. from emp
  115. where comm=0 or comm is null or ename not like '%t_';
  116. 30. 案例:查询工资高于3000或者部门编号是30的员工的姓名,职位,工资,入职时间以及所属部门的编号
  117. select ename,job,sal,hiredate,deptno
  118. from emp
  119. where sal>3000 or deptno=30;
  120. 31. 案例:查询不是30号部门的员工的所有信息
  121. select *
  122. from emp
  123. where deptno!=30;
  124. 32. 案例:查询奖金不为空的员工的所有信息
  125. select *
  126. from emp
  127. where comm is not null;
  128. 33. 案例:查询emp表中所有员工的编号,姓名,职位,根据员工的编号进行降序排列
  129. select empno,ename,job
  130. from emp
  131. order by empno desc;
  132. 34. 案例:查询emp表中部门编号是10号或者30号中,所有员工姓名,职务,工资,根据工资进行升序排列
  133. select ename,job,sal
  134. from emp
  135. where deptno in(10,30)
  136. order by sal;
  137. 35. 案例:查询emp表中所有的数据,然后根据部门的编号进行升序排列,如果部门编号一致,根据员工的编号进行降序排列
  138. select *
  139. from emp
  140. order by deptno,empno desc;
  141. 36. 案例:查询emp表中工资高于1000或者没有上级领导的员工的编号,姓名,工资,所属部门的编号,以及上级领导的编号,根据部门编号进行降序排列,如果部门编号一致根据工资进行升序排列。
  142. select empno,ename,sal,deptno,mgr
  143. from emp
  144. where sal>1000 or mgr is null
  145. order by deptno desc,sal;
  146. 37. 案例:查询emp表中名字中不包含S的员工的编号,姓名,工资,奖金,根据工资进行升序排列,如果工资一致,根据编号进行降序排列
  147. select empno,ename,sal,comm
  148. from emp
  149. where ename not like '%s%'
  150. order by sal,empno desc;
  151. 38. 案例:统计emp表中员工的总数量
  152. select count(*)
  153. from emp;
  154. 39. 案例:统计emp表中获得奖金的员工的数量
  155. select count(*)
  156. from emp
  157. where comm>0;
  158. 40. 案例:求出emp表中所有的工资累加之和
  159. select sum(sal)
  160. from emp;
  161. 41. 案例:求出emp表中所有的奖金累加之和
  162. select sum(comm)
  163. from emp;
  164. 42. 案例:求出emp表中员工的平均工资
  165. select avg(sal)
  166. from emp;
  167. 43. 案例:求出emp表中员工的平均奖金
  168. select avg(comm)
  169. from emp;
  170. 44. 案例:求出emp表中员工的最高工资
  171. select max(sal)
  172. from emp;
  173. 45. 案例:求出emp表中员工编号的最大值
  174. select max(empno)
  175. from emp;
  176. 46. 案例:查询emp表中员工的最低工资。
  177. select min(sal)
  178. from emp;
  179. 47. 案例:查询emp表中员工的人数,工资的总和,平均工资,奖金的最大值,奖金的最小值,并且对返回的列起别名。
  180. select count(*) 总人数,sum(sal) 工资总和,avg(sal) 平均工资,max(comm) 最高奖金, min(comm) 最低奖金
  181. from emp;

数学相关函数

  1. 1. 向下取整 floor(num)
  2. select floor(3.8);
  3. 2. 四舍五入 round(num)
  4. select round(23.8);
  5. 3. 四舍五入 round(num,m) m代表小数位数
  6. select round(23.879,2);
  7. 4. 非四舍五入 truncate(num,m) m代表小数位数
  8. select truncate(23.879,2);
  9. 5. 随机数 rand() 0-1随机数
  10. select rand();
  11. 6. 3-5的随机整数 345 0-2+2
  12. select floor(rand()*3+3);

分组查询

  1. 格式:
  2. group by 分组字段名

每个或每种什么,就以什么进行分组查询

  1. 1. 查询每个部门的平均工资
  2. select deptno,avg(sal)
  3. from emp
  4. group by deptno;
  5. 2. 查询每种职业的最高工资
  6. select job,max(sal)
  7. from emp
  8. group by job;
  9. 3. 查询每个部门的人数
  10. select deptno,count(*)
  11. from emp
  12. group by deptno;
  13. 4. 查询工资大于1000的员工中每个部门的最高工资
  14. select deptno,max(sal)
  15. from emp
  16. where sal>1000
  17. group by deptno;
  18. 5. 查询每个领导的手下人数
  19. select mgr,count(*)
  20. from emp
  21. where mgr is not null
  22. group by mgr;

多字段分组在group by后面写多个字段名

  1. 1. 查询每个部门,每种职业的平均工资
  2. select deptno,job,avg(sal)
  3. from emp
  4. group by deptno,job;
  5. 2. 查询emp表中每个部门的编号、人数、工资总和、根据人数进行升序排序,如果人数一致根据工资总和降序排序
  6. select deptno,count(*),sum(sal)
  7. from emp
  8. group by deptno
  9. order by count(*),sum(sal) desc;
  10. select deptno,count(*) c,sum(sal) s
  11. from emp
  12. group by deptno
  13. order by c,s desc;
  14. 3. 查询工资在1000~3000之间的员工信息,每个部门的编号,平均工资,最低工资,最高工资,根据平均工资进行升序排序
  15. select deptno,avg(sal) a,min(sal),max(sal)
  16. from emp
  17. where sal between 1000 and 3000
  18. group by deptno
  19. order by a;
  20. 4. 查询有上级领导的员工,每个职业的人数,工资总和,平均工资,根据人数进行降序排序,如果人数一致则根据平均工资进行升序排序
  21. select job,count(*) c,sum(sal),avg(sal) a
  22. from emp
  23. where mgr is not null
  24. group by job
  25. order by c desc,a;

having

where 后面只能写普通字段的条件,不能写聚合函数的条件 把聚合函数的条件写在having后面

  1. 各个关键字的顺序
  2. select .....
  3. from ....
  4. where ....
  5. group by ....
  6. having ....
  7. order by .....
  8. limit ....;
  1. 1. 查询每个部门的平均工资,要求平均工资大于2000
  2. select deptno,avg(sal) a
  3. from emp
  4. where a>2000
  5. group by deptno;
  6. select deptno,avg(sal) a
  7. from emp
  8. group by deptno
  9. having a>2000;
  10. 2. 查询每个分类category_id的平均单价 要求平均单价低于100
  11. select category_id,avg(price) a
  12. from t_item
  13. group by category_id
  14. having a<100;
  15. 3. 查询分类id238917的两个分类的平均单价
  16. select category_id,avg(price)
  17. from t_item
  18. where category_id in(238,917)
  19. group by category_id;
  20. 4. 查询emp表中每个部门的平均工资高于2000的部门编号,部门人数,平均工资,最后根据平均工资降序排序
  21. select deptno,count(*),avg(sal) a
  22. from emp
  23. group by deptno
  24. having a>2000
  25. order by a desc;
  26. 5. 查询emp表中工资在1000-3000之间的员工,每个部门的编号,工资总和,平均工资,过滤掉平均工资低于2000的部门,最后按照平均工资进行升序排序
  27. select deptno,sum(sal),avg(sal) a
  28. from emp
  29. where sal between 1000 and 3000
  30. group by deptno
  31. having a>=2000
  32. order by a;

提高题

  1. 1. 查询每年入职的人数
  2. select extract(year from hiredate) year,count(*)
  3. from emp
  4. group by year;
  5. 2. 查询员工表中最高的平均工资
  6. select avg(sal) a
  7. from emp
  8. group by deptno
  9. order by a desc
  10. limit 0,1;

子查询(嵌套查询)

  1. 3. 查询emp表中工资最高的员工信息
  2. select max(sal)
  3. from emp; // 5000
  4. select *
  5. from emp
  6. where sal=(
  7. select max(sal)
  8. from emp
  9. );
  10. 4. 查询高于平均工资的员工信息
  11. select avg(sal)
  12. from emp;
  13. select *
  14. from emp
  15. where sal>(
  16. select avg(sal)
  17. from emp
  18. );
  19. 5. 查询工资高于20号部门最高工资的员工信息
  20. select *
  21. from emp
  22. where sal>(
  23. select max(sal)
  24. from emp
  25. where deptno=20
  26. );
  27. 6. 查询和jones相同工作的其它员工信息
  28. select job
  29. from emp
  30. where ename='jones';
  31. select *
  32. from emp
  33. where job=(
  34. select job
  35. from emp
  36. where ename='jones'
  37. ) and ename!='jones';
  38. 7. 查询工资最低的员工的同事们的信息(同事=同一个部门)
  39. 1. 得到最低工资
  40. select min(sal)
  41. from emp;
  42. 2. 通过最低工资找到部门编号
  43. select deptno
  44. from emp
  45. where sal=(
  46. select min(sal)
  47. from emp
  48. );
  49. 3. 通过部门编号查询该部门的人,还要去掉工资最低的
  50. select *
  51. from emp
  52. where deptno in(
  53. select deptno
  54. from emp
  55. where sal=(
  56. select min(sal)
  57. from emp
  58. )
  59. ) and sal != (
  60. select min(sal)
  61. from emp
  62. );
  63. 8. 查询最后入职的员工信息
  64. select max(hiredate)
  65. from emp;
  66. select *
  67. from emp
  68. where hiredate=(
  69. select max(hiredate)
  70. from emp
  71. );
  72. 9. 查询king的部门编号和部门名称(需要用到dept表)
  73. select deptno
  74. from emp
  75. where ename='king';
  76. select dname
  77. from dept
  78. where deptno=(
  79. select deptno
  80. from emp
  81. where ename='king'
  82. );
  83. 10. 查询有员工的部门信息(想办法过滤掉40号部门,因为它没员工)
  84. select distinct deptno
  85. from emp;
  86. select *
  87. from dept
  88. where deptno in(
  89. select distinct deptno
  90. from emp
  91. );
  92. 11. 查询平均工资最高的部门信息(难度最高)需要考虑并列最高的问题
  93. (1). 得到最高的平均工资
  94. select avg(sal) a
  95. from emp
  96. group by deptno
  97. order by a desc
  98. limit 0,1;
  99. (2). 通过最高平均工资查部门编号
  100. select deptno
  101. from emp
  102. group by deptno
  103. having avg(sal)=(
  104. select avg(sal) a
  105. from emp
  106. group by deptno
  107. order by a desc
  108. limit 0,1
  109. );
  110. (3). 通过部门编号查部门信息
  111. select *
  112. from dept
  113. where deptno in(
  114. 上面一坨
  115. );
  • 子查询总结:
  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. 1. 查询每一个员工的员工姓名和对应的部门名称
  2. select e.ename,d.dname
  3. from emp e,dept d
  4. where e.deptno=d.deptno;
  5. 2. 查询在new york工作的员工姓名
  6. select e.ename
  7. from emp e,dept d
  8. where e.deptno=d.deptno and d.loc='new york';

等值连接和内连接

等值连接和内连接查询到的是一样的结果,为两张表的交集数据

  1. 1. 等值连接
  2. select *
  3. from A,B
  4. where A.x=B.x and A.age=18;
  5. 2. 内连接
  6. select *
  7. from A
  8. [inner] join B on A.x=B.x
  9. where A.age=18;
  1. 案例:查询每一个员工的员工姓名和对应的部门名称
  2. select e.ename,d.dname
  3. from emp e
  4. join dept d on e.deptno=d.deptno;

外连接

外连接查询到的是一张表的全部数据和另外一张表的交集数据

  1. 格式
  2. select *
  3. from A
  4. left/right [outer] join B on A.x=B.x
  5. where A.age=18;
  1. 查询所有的部门名和其对应的员工名
  2. select d.dname,e.ename
  3. from emp e
  4. right join dept d on e.deptno=d.deptno;

关联查询总结

  1. 查询方式有三种:等值连接、内连接、外连接
  2. 如果查询的数据是两张表的交集数据使用等值或内连接(推荐)
  3. 如果查询的数据是一张表的全部数据和另外一张表的交集数据使用外连接

练习

  1. 1. 每个部门的人数,根据人数降序排序
  2. select deptno,count(*) c
  3. from emp
  4. group by deptno
  5. order by c desc;
  6. 2. 每个部门中,每个主管的手下人数
  7. select deptno,mgr,count(*)
  8. from emp
  9. where mgr is not null
  10. group by deptno,mgr;
  11. 3. 每种工作的平均工资
  12. select job,avg(sal)
  13. from emp
  14. group by job;
  15. 4. 每年的入职人数
  16. select extract(year from hiredate) year,count(*)
  17. from emp
  18. group by year;
  19. 5. 少于等于3个人的部门信息
  20. select d.*
  21. from emp e
  22. right join dept d on e.deptno=d.deptno
  23. group by deptno
  24. having count(e.ename)<=3;
  25. 6. 拿最低工资的员工信息
  26. select * from emp
  27. where sal=(
  28. select min(sal)
  29. from emp
  30. );
  31. 7. 只有一个下属的主管信息
  32. select mgr
  33. from emp
  34. where mgr is not null
  35. group by mgr
  36. having count(*)=1;
  37. select *
  38. from emp
  39. where empno in(
  40. select mgr
  41. from emp
  42. where mgr is not null
  43. group by mgr
  44. having count(*)=1
  45. );
  46. 8. 每月发工资最多的部门信息
  47. (1).得到最高的工资总和
  48. select sum(sal) s
  49. from emp
  50. group by deptno
  51. order by s desc
  52. limit 0,1;
  53. (2).通过工资总和查部门的编号
  54. select deptno
  55. from emp
  56. group by deptno
  57. having sum(sal)=(
  58. select sum(sal) s
  59. from emp
  60. group by deptno
  61. order by s desc
  62. limit 0,1
  63. );
  64. (3).通过部门编号查部门信息
  65. select *
  66. from dept
  67. where deptno in (
  68. 上面一坨
  69. );
  70. 9. 下属最多的人,查询其个人信息
  71. (1).得到下属最多的人数
  72. select count(*) c
  73. from emp
  74. group by mgr
  75. order by c desc
  76. limit 0,1;
  77. (2).通过人数找mgr
  78. select mgr
  79. from emp
  80. group by mgr
  81. having count(*)=(
  82. select count(*) c
  83. from emp
  84. group by mgr
  85. order by c desc
  86. limit 0,1
  87. );
  88. (3).通过mgr找个人信息
  89. select *
  90. from emp
  91. where empno in(
  92. 上面一坨
  93. );
  94. 10. 拿最高工资员工的同事信息
  95. select *
  96. from emp
  97. where deptno = (
  98. select deptno
  99. from emp
  100. where sal=(
  101. select max(sal)
  102. from emp
  103. )
  104. ) and sal !=(
  105. select max(sal)
  106. from emp
  107. );
  108. 11. 和最后入职的员工在同一部门的员工信息 实现流程和第十题一样
  109. select max(hiredate)
  110. from emp;
  111. select deptno
  112. from emp
  113. where hiredate=(
  114. select max(hiredate)
  115. from emp
  116. );
  117. select *
  118. from emp
  119. where deptno=(
  120. select deptno
  121. from emp
  122. where hiredate=(
  123. select max(hiredate) from emp
  124. )
  125. ) and hiredate!=(
  126. select max(hiredate)
  127. from emp
  128. );
  129. 12. 查询平均工资高于20号平均工资的部门信息
  130. select avg(sal)
  131. from emp
  132. where deptno=20;
  133. select deptno
  134. from emp
  135. group by deptno
  136. having avg(sal)>(
  137. select avg(sal)
  138. from emp
  139. where deptno=20
  140. );
  141. select *
  142. from dept
  143. where deptno in(
  144. select deptno
  145. from emp
  146. group by deptno
  147. having avg(sal)>(
  148. select avg(sal)
  149. from emp
  150. where deptno=20
  151. )
  152. );
  153. 13. 查询员工信息和员工对应的部门名称
  154. select e.*,d.dname
  155. from emp e
  156. join dept d on e.deptno=d.deptno;
  157. 14. 查询员工信息,部门名称,所在城市
  158. select e.*,d.dname,d.loc
  159. from emp e
  160. join dept d on e.deptno=d.deptno;
  161. 15. 查询Dallas市所有的员工信息
  162. select e.*
  163. from emp e
  164. join dept d
  165. on e.deptno=d.deptno
  166. where d.loc='dallas';
  167. 16. 计算每个城市的员工数量
  168. select d.loc,count(e.empno)
  169. from emp e
  170. right join dept d on e.deptno=d.deptno
  171. group by d.loc;
  172. 17. 查询员工信息和他的主管姓名 凡是自关联 把一张表当成两张表
  173. select e.ename,m.ename
  174. from emp e
  175. join emp m on e.mgr = m.empno;
  176. 18. 员工信息,员工主管名字,部门名
  177. select e.ename,m.ename,d.dname
  178. from emp e
  179. join emp m on e.mgr = m.empno
  180. join dept d on e.deptno=d.deptno;
  181. 19. 员工名和他所在部门名
  182. select e.ename,d.dname
  183. from emp e
  184. join dept d on e.deptno=d.deptno;
  185. 20. 案例:查询emp表中所有员工的姓名以及该员工上级领导的编号,姓名,职位,工资
  186. select e.ename,m.empno,m.ename,m.job,m.sal
  187. from emp e
  188. left join emp m on e.mgr=m.empno;
  189. 21. 案例:查询emp表中名字中没有字母'K'的所有员工的编号,姓名,职位以及所在部门的编号,名称,地址
  190. select e.empno,e.ename,e.job,d.deptno,d.dname,d.loc
  191. from emp e
  192. left join dept d on e.deptno=d.deptno
  193. where e.ename not like '%k%';
  194. 22. 案例:查询dept表中所有的部门的所有的信息,以及与之关联的emp表中员工的编号,姓名,职位,工资
  195. select d.*,e.empno,e.ename,e.job,e.sal
  196. from emp e
  197. right join dept d on e.deptno=d.deptno;