Mysql 分组查询/子查询/关联查询【总结】

1、分组查询:group by

通常和聚合函数结合使用,以组为单位进行统计,一般情况下,题目中每个XX就在group by后面写这个XX;

  • 例:查询每个部门的最高工资:
    select deptno,max(sal) from emp group by deptno;
  • 例:查询每个分类下的商品最大价格:
    select category_id,max(price) from t_item group by category_id;
  • 例:查询每个部门中工资大于1500的人数:
    select deptno,sal from emp where sal > 1500 group by deptno;
  • 例:查询每个领导手下的人数:
    select mgr,count(*) from emp where mgr is not null group by mgr;

如果需要使用多个字段进行分组,直接在group by后面写多个字段名通过逗号分隔:

  • 例:查询按每个部门下每个领导的手下人数:
    select deptno,mgr,count(*) from emp where mgr is not null group by deptno,mgr;

having:要写在group by后面和它结合使用:

  1. where:后面只能写普通字段的条件不能写聚合函数;
  2. having:后面可以写普通字段条件也可以写聚合函数推荐在having后面只写聚合函数;
  • 例:查询每个部门的平均工资,要求平均工资大于2000:
    select deptno,avg(sal) a from emp group by deptno having a > 2000;
  • 例:查询每个分类的平均单价,过滤掉平均单价低于100的:
    select category_id,avg(price) a from t_item group by category_id having a >= 100;

2、子查询:

  • 例:查询emp表工资中最高的员工信息:
    正常情况下需要查出最高工资的员工,然后再查出员工的信息:
    select max(sal) from emp;(查询结果为5000)
    select * from emp where sal = 5000;
    使用子查询:
    select * from emp where sal = (select max(sal) from emp);
  • 例:查询工资最低的员工的所在部门的同事信息:
    首先查询到工资最低的员工:
    select min(sal) from emp;
    通过最低工资找到所在部门编号:
    select deptno from emp where sal = (select min(sal) from emp);
    通过编号找到其他的员工信息:
    select * from emp where deptno = (select deptno from emp where sal = (select min(sal) from emp));
  • 扩展题:查询平均工资最高的部门信息:
    得到每个部门的平均工资:
    select deptno,avg(sal) from emp group by deptno;
    得到最高的平均工资:
    select avg(sal) a from emp group by deptno order by a desc limit 0,1;
    通过最高的平均工资得到部门编号:(这里为了严谨考虑有多个部门工资平均值相同且为最高平均工资的情况)
    select deptno from emp group by deptno having avg(sal) = (select avg(sal) a from emp group by deptno order by a desc limit 0,1);
    通过部门编号获得部门信息:
    select * from dept where deptno in(select deptno from emp group by deptno having avg(sal) = (select avg(sal) a from emp group by deptno order by a desc limit 0,1));

子查询可以写在什么位置:

  1. 写在where或having后面,当做查询条件的值;
  2. 写在创建表的时候,把查询结果保存成一张新的表;
  3. 写在from的后面当成一张虚拟表,必须有别名

3、关联查询:

同时查询多张表的数据称为关联查询(能查询到的只能是两张表的交集)。

  • 例:查询每一个员工的姓名和对应的部门名称:
    select e.ename,d.dname from emp e,dept d where e.deptno = d.deptno;

笛卡尔积:如果关联查询不写关联关系则结果为两张表的乘积,这个乘积称为笛卡尔积,笛卡尔积为一种错误的查询结果,切记工作中不要出现。

关联查询的查询方式:等值连接和内连接

  • 等值连接: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; [inner]可以省略不写

等值连接和内连接查询到的内容一样,都为两张表中有关联关系的数据(交集部分)。

  • 例:查询每一个员工的姓名和对应部门名称:(用内连接的方式)
    select e.ename,d.deptno from emp e join dept d on e.deptno = d.deptno;

  • 外连接:内连接和等值连接查询到的是交集数据,外连接查询到的是某一张表的全部数据 + 另一张表的交集数据。

  • 左/右外连接:select * from A left/right join B on A.x = B.x where A.age = 18;(左外连接就是以左边的表即A为主表和右边表的交集)

关联查询总结:

  • 关联查询的查询方式:等值连接、内连接、外连接;
  • 如果想查询的数据为两张表的交集数据使用等值连接和内连接(推荐);
  • 如果查询的数据是一张表的全部数据和领一张表的交集数据则使用外连接;

猜你喜欢

转载自blog.csdn.net/weixin_44296929/article/details/108592882