zoukankan      html  css  js  c++  java
  • 第七节:分组查询

    一、分组查询

      1、语法格式

        利用 group by 子句将表中的数据分成若干组:

    select 分组函数, 列(需要出现在 group by 的后面)
    from 表
    【where 筛选条件】
    group by 分组的列表
    【order by 子句】
    

        注意:查询列表比较特殊,要求是分组函数和 group by 后出现的字段

       

      2、数据筛选

        (1)分组前筛选

          使用 where 可以做分组前筛选,从表中直接筛选掉不符合条件的数据。

        (2)分组后筛选

          分组后使用 having 过滤分组:

          ① 行已经被分组;

          ② 使用了组函数;

          ③ 满足 having 子句中条件的分组将被显示;

          

        注意:非法使用组函数

          ① 不能在 where 子句中使用组函数;

          ② 可以在 having 子句中使用组函数;

        

      3、分组查询特点

        (1)分组查询中的筛选条件分为两类:

      数据源 位置 关键字 使用聚合函数
    分组前筛选 原始表 group by子句前面 where 不可以
    分组后筛选 分组后的结果集 group by子句后面 having 可以

        (2)group by 支持单个字段分组,多个字段分组(多个字段之间使用逗号隔开,没有顺序要求)表达式或函数(相对较少)

        (3)也可以添加排序(排序放在整个分组查询的最后)

        思考1:分组函数做筛选能不能放在where后面

        不能!!!

        思考2:使用顺序where——group by——having

        一般来讲,能用分组前筛选的,尽量使用分组前筛选,提高效率

    二、案例

      1、简单分组查询

        (1)查询每个工种的最高工资

    SELECT 
      MAX(salary),
      job_id 
    FROM
      employees 
    GROUP BY job_id ;
    

        (2)查询每个工种的员工平均工资

    SELECT 
      AVG(salary),
      job_id 
    FROM
      employees 
    GROUP BY job_id ;
    

        (3)查询每个位置上的部门个数

    SELECT 
      COUNT(*),
      location_id 
    FROM
      departments 
    GROUP BY location_id ;
    

      2、添加筛选条件(分组前筛选)

        (1)查询邮箱中包含 a 字符的,每个部门的平均工资

    SELECT 
      AVG(salary),
      department_id 
    FROM
      employees 
    WHERE email LIKE '%a%' 
    GROUP BY department_id ;
    

      

        (2)查询有奖金的每个领导手下员工的最高工资

    SELECT 
      MAX(salary),
      manager_id 
    FROM
      employees 
    WHERE commission_pct IS NOT NULL 
    GROUP BY manager_id ;
    

      

      3、添加分组后的筛选条件

        (1)查询哪个部门的员工个数大于2

          ① 查询每个部门的员工个数

    SELECT 
      COUNT(*),
      department_id 
    FROM
      employees 
    GROUP BY department_id ;
    

      

          ② 根据①的结果进行筛选,查询哪个部门的员工个数 > 2

    SELECT 
      COUNT(*),
      department_id 
    FROM
      employees 
    GROUP BY department_id 
    HAVING COUNT(*) > 2 ;
    

     

        (2)查询每个工种有奖金的员工的最高工资>12000的工种编号和最高工资

          ① 查询每个工种有奖金的员工的最高工资

    SELECT 
      job_id,
      MAX(salary) 
    FROM
      employees 
    WHERE commission_pct IS NOT NULL 
    GROUP BY job_id ;
    

      

          ② 查询最高工资 > 12000

    SELECT 
      job_id,
      MAX(salary) 
    FROM
      employees 
    WHERE commission_pct IS NOT NULL 
    GROUP BY job_id 
    HAVING MAX(salary) > 12000 ;
    

      

        (3)查询领导编号>102的每个领导手下的最低工资>5000的领导编号是哪个,以及其最低工资

          ① 查询每个领导手下的最低工资

    SELECT 
      manager_id,
      MIN(salary) 
    FROM
      employees 
    GROUP BY manager_id ;
    

      

          ② 添加筛选条件,编号 > 102

    SELECT 
      manager_id,
      MIN(salary) 
    FROM
      employees 
    WHERE manager_id > 102 
    GROUP BY manager_id ;
    

            ③ 添加分组后筛选,最低工资大于 5000

    SELECT 
      manager_id,
      MIN(salary) 
    FROM
      employees 
    WHERE manager_id > 102 
    GROUP BY manager_id 
    HAVING MIN(salary) > 5000 ;
    

      

      4、添加排序

        (1)每个工种有奖金的员工的最高工资>6000的工种编号和最高工资,按最高工资升序

    SELECT 
      job_id,
      MAX(salary) m 
    FROM
      employees 
    WHERE commission_pct IS NOT NULL 
    GROUP BY job_id 
    HAVING m > 6000 
    ORDER BY m ;
    

        (2)查询每个部门,每个工种的平均工资,且按平均工资的高低显示

    SELECT 
      AVG(salary),
      department_id,
      job_id 
    FROM
      employees 
    GROUP BY department_id,
      job_id 
    HAVING AVG(salary) > 10000 
    ORDER BY AVG(salary) DESC ;
    

      

      5、按多个字段分组,将多个分组字段相同的分为一组

        (1)查询每个工种每个部门的最低工资,并按最低工资降序

    SELECT 
      MIN(salary),
      job_id,
      department_id 
    FROM
      employees 
    GROUP BY department_id,
      job_id 
    ORDER BY MIN(salary) DESC ;
    

      

      6、按表达式或函数分组

        (1)按员工姓名的长度分组,查询每一组的员工个数,筛选员工个数 > 5 的有哪些

          ① 查询每个长度的员工个数

    SELECT 
      LENGTH(last_name) len_name,
      COUNT(*) 
    FROM
      employees 
    GROUP BY len_name ;
    

      

          ② 添加筛选条件

    SELECT 
      LENGTH(last_name) len_name,
      COUNT(*) 
    FROM
      employees 
    GROUP BY LENGTH(last_name) 
    HAVING COUNT(*) > 5 ;
    

          也可以使用别名:

    SELECT 
      LENGTH(last_name) len_name,
      COUNT(*) 员工个数 
    FROM
      employees 
    GROUP BY LENGTH(last_name) 
    HAVING 员工个数 > 5 ;
    

      

    三、练习

      1、查询各job_id的员工工资的最大值,最小值,平均值,总和,并按job_id升序

    SELECT 
      MAX(salary),
      MIN(salary),
      AVG(salary),
      SUM(salary),
      job_id 
    FROM
      employees 
    GROUP BY job_id 
    ORDER BY job_id ;
    

      2、查询员工最高工资和最低工资的差距(DIFFERENCE)

    SELECT 
      MAX(salary) - MIN(salary) DIFFRENCE 
    FROM
      employees ;
    

      3、查询各个管理者手下员工的最低工资,其中最低工资不能低于6000,没有管理者的员工不计算在内

    SELECT 
      MIN(salary),
      manager_id 
    FROM
      employees 
    WHERE manager_id IS NOT NULL 
    GROUP BY manager_id 
    HAVING MIN(salary) >= 6000 ;
    

      4、查询所有部门的编号,员工数量和工资平均值,并按平均工资降序

    SELECT 
      department_id,
      COUNT(*),
      AVG(salary) a 
    FROM
      employees 
    GROUP BY department_id 
    ORDER BY a DESC ;
    

      5、选择具有各个job_id的员工人数

    SELECT 
      COUNT(*) 个数,
      job_id 
    FROM
      employees 
    GROUP BY job_id ;
    
  • 相关阅读:
    Jquery简略API使用
    JS全部API笔记
    实现nginx的负载均衡和反向代理
    HashMap在Java1.7与1.8中的区别
    数据库设计三大范式
    Java集合
    Object类有哪些方法
    spring mvc出现 Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'endtime'
    int和Integer的区别
    第二次面试-科大讯飞(卒)
  • 原文地址:https://www.cnblogs.com/niujifei/p/14886376.html
Copyright © 2011-2022 走看看