MySQL(三)----基础二

本文详细介绍了SQL中的分组函数,如SUM、AVG、MAX、MIN和COUNT,以及它们的特点和使用场景。内容包括分组函数对不同类型数据的处理方式,COUNT(*)与COUNT(1)的区别,DISTINCT的使用,以及DATEDIFF函数计算日期差值。此外,还讲解了ORDER BY用于排序的基本语法和注意事项,以及GROUP BY进行数据分组的规则和配合HAVING子句筛选条件的方法。文章通过多个实例展示了如何在实际查询中运用这些概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

3.分组函数

 

功能:用作统计使用,又称为聚合函数或统计函数

分类:sum求和 , avg求平均值 , max最大值,min最小值,count计算个数

特点:

  1. sum,avg可以处理数值类型 , max ,min ,count可以处理任何类型

  2. 以上分组函数忽略null值

  3. 可以和distinct(去重)搭配只用

  4. 使用count(*)统计行数

  5. 和分组函数一同查询的字段要求是group by后的字段

 

基本使用

 

  1. count的详细介绍

    count(1)是在没行的前面加了一列常量1,然后计算有多少行

  1. -- 基本使用
    SELECT SUM(salary) , MAX(salary) , MIN(salary) , COUNT(commission_pct) , AVG(salary)
    FROM employees;
    ​
    -- 以上都是忽略null值的,以count为例 , 表中有107条数据
    -- 结果:35
    SELECT COUNT(commission_pct) 
    FROM employees;
    ​
    -- 可以支持distinct去重使用
    -- 结果:11   有107条数据,去重过后剩余11条
    SELECT COUNT(DISTINCT department_id) 
    FROM employees;
    ​
    -- count的详解
    -- count的参数如果是字段的话,会作用到这一整列 , 但是使用count(*)会计算所有的行数
    -- 另外count(1)可以计算所有的行数
    SELECT count(*)
    FROM employees;
    ​
    SELECT count(1)
    FROM employees;
    ​
    -- count里的参数可以常量 , 和是1的类似 , 但是性能不好

     

3.1.测试

 

相差天数使用的函数可以用DATEDIFF , TIMEDIFF相差时间 xx:xx:xx表示

-- 查询员工表中的最大入职时间和最小入职时间的相差天数
​
SELECT DATEDIFF(MAX(hiredate),MIN(hiredate)) AS day
FROM employees;
​
​
-- 查询部门编号为90的员工的个数
​
SELECT COUNT(*) 
FROM employees
WHERE department_id = 90;

 

4.排序(order by)

  1. 语法:

    select 查询列表

    from 表

    【where 筛选条件】

    order by 排序列表 【ASC | DESC】

  2. 特点:

    1.ASC 代表升序 , DESC代表降序。 不写默认是ASC

    2.order by 子句单个字段,多个字段,表达式,别名,函数,表达式排序

    3.order by 子句放在查询语句的最后面

    4.子句中可以放分组函数

     

  3. 案例

-- 查询部门编号>=90,按照入职时间排序 【添加筛选条件】

SELECT * FROM employees WHERE department_id >= 90 ORDER BY hiredate DESC;
-- 按照年薪的高低显示员工的信息和 年薪【按照表达式排序】

SELECT first_name , job_id , salary , (IFNULL(salary,0))*12 AS 年薪 FROM employees ORDER BY (IFNULL(salary,0))*12;
-- 按照年薪的高低显示员工的信息和 年薪【按照别名排序】

-- 和上面的完全相同
SELECT first_name , job_id , salary , (IFNULL(salary,0))*12 AS 年薪 FROM employees ORDER BY 年薪;
-- 按照姓名的长度显示员工的姓名和工资 【按照函数排序】

SELECT LENGTH(IFNULL(first_name,'')) AS name_length , job_id , salary from  employees ORDER BY name_length;
-- 查询员工的信息,要求先按照工资排序,再按照员工编号排序【按多个字段进行排序】

SELECT  first_name , job_id , salary FROM employees ORDER BY salary DESC, job_id; 

4.1.测试

 

-- 1. 查询员工的姓名和部门号和年薪,按年薪降序 按姓名升序
SELECT last_name , manager_id , (IFNULL(salary,0))*12 AS 年薪 
FROM employees 
ORDER BY 年薪 DESC , last_name;
-- 2. 选择工资不在8000-17000的员工的姓名和工资,按工资降序
SELECT last_name , salary 
from employees where 
-- salary NOT BETWEEN  7000 AND 17000
salary < 7000 OR salary >17000 
ORDER BY salary DESC;
​
或者是
-- 3. 查询邮箱中包含E的员工的信息,并先按照邮箱的子节数降序 , 再按照部门号升序
SELECT * 
FROM employees
WHERE email like  '%E%'
ORDER BY LENGTH(email) DESC , department_id;
​

5.分组 (grounp by)

  1. 语法:

    select column , grounp_function(column) 4

    from table 1

    [where condition] 2

    [group by group_by_expression] 3

    [order by column] 5

  2. 特点:

    1. group by 后面跟的可以是字段,也可以是表达式

    2. group by 后面和having后面都支持别名

    3. 可以按照多个字段进行分组

     

 

执行顺序应该是上面标注的

 

处理分组的问题:

  1. 要知道分组是以某个字段进行分组的 ,那么影响到的是行,相同的字段的有一个或多个行的数据

  2. 拿到了这个字段的行之后,然后再在这些行中对某个字段使用分组函数

分组和分组函数的配合使用

  1. 要知道,如果单单使用分组函数 , 会作用到整个列上

  2. 如果是使用了分组,然后使用分组函数 , 就是将分组函数作用到每个组

 

关于书写sql语句的步骤(单表的,以后会在后面总结多表连接的)

(因为喜欢先分组再判断条件,所以见谅)

考虑步骤就是根据上面我标的步骤来

  1. select 写完之后,column不要先写

  2. 直接写应该在哪个表中

  3. 然后判断分组

  4. 判断条件是不是涉及到分组函数 , 如果有在having中,没有在where中

  5. 写where条件

  6. 写having条件

  7. 如果有排序先排序

  8. 最后写column

另外关于条件,既可以在where语句中,也可以在分组函数中,要判断好依据的条件在哪

其实分组函数中可以有的条件很少,就是那几个分组函数的返回值基础上的,很容易辨别 但是如果条件是根据分组函数来进行判断,就要涉及到having , 在having 里面才能使用分组函数作为条件,具体例子在下面有介绍

 

5.1.测试

-- 案例1:查询每个工种的最高工资
SELECT job_id , MAX(salary) 
FROM employees
GROUP BY job_id;
​
-- 案例2:查询每个位置上的部门个数
SELECT location_id , count(department_id)
FROM departments
GROUP BY location_id;
-- 案例3:(添加筛选条件) 查询邮箱中包含a字符 , 每个部门的平均工资
SELECT department_id , AVG(salary)
FROM employees
where email like '%a%'
GROUP BY department_id;
​
-- 案例4:(添加筛选条件)查询有奖金的每个领导手下员工的最高工资
-- 根据上面的步骤来
/*
    在employees表中
    以manager_id分组
    条件是有奖金的,显然不是和分组函数有关的
    写where
    没有排序
    写colomns
*/
​
SELECT manager_id , MAX(salary)
FROM employees
WHERE commission_pct is not null
GROUP BY manager_id;
​
-- 案例5:(添加复杂的筛选条件)查询那个部门的员工的个数>2
/*
    确认是employees表
    确定是以部门分组
    条件个数大于2 , 能统计个数的是count分组函数 , 所以应该在分组函数这边判断 , 所以用到having
    没有where
    写having
    没有order by
    写colomns
*/
SELECT department_id , COUNT(*) AS count
FROM employees
GROUP BY department_id
HAVING count >= 2;
​
-- 案例6:(添加复杂的筛选条件)查询每个工种有奖金的员工的最高工资>12000的工种编号和最高工资
-- 最后一次分析
/*
    在employees表中
    GROUP BY 工种job_id
    判断条件   有奖金是在where中, 最高工资只能是max分组函数,在having中
    WHERE 中  有奖金 
    没有order by
    写columns
*/
​
SELECT job_id , MAX(salary)
FROM employees 
WHERE commission_pct is not null
GROUP BY job_id
​
-- 案例7:(添加复杂的筛选条件)查询领导编号>102的每个领导手下的最低工资>5000的领导编号是哪个 , 以及最低工资
​
SELECT manager_id , MIN(salary)
FROM employees
WHERE manager_id > 102
GROUP BY manager_id
HAVING MIN(salary) > 5000;
​
-- 案例8:(group by后面跟表达式) 以姓名的长度分组 , 输出相同长度的姓名的平均薪资
​
-- 案例9:(多组并且和order by一起使用) 查询每个部门每个工种的平均工资,并以降序排列
​
​
​
​
-- 测试
-- 1.查询各个job_id的员工工资的最大值,最小值,平均值,总和,并按照job_id升序
​
SELECT MAX(salary) AS 最大值  , MIN(salary) AS 最小值 , AVG(salary) 平均值 , SUM(salary) 总和
FROM employees
​
GROUP BY job_id
ORDER BY job_id;
-- 2.查询员工最高工资和最低工资的差距
SELECT (MAX(salary) - MIN(salary)) AS 'DIFFERENCE'
FROM employees;
​
-- 3.查询所有部门编号,员工数目和平均工资值 , 并且按照平均工资降序
SELECT department_id AS 部门编号 , COUNT(*) AS 员工数目 , AVG(salary) AS 平均工资
FROM employees
​
GROUP BY department_id
 
ORDER BY AVG(salary) DESC;
​
-- 4.查询各个管理者手下员工的最低工资,其中最低工资不能少于6000 , 没有管理者的员工不计算在内
​
SELECT manager_id , MIN(salary)
FROM employees
WHERE manager_id is not NULL
GROUP BY manager_id
HAVING MIN(salary) >= 6000;
​
-- 5.选择具有各个job_id的员工人数
SELECT job_id , count(*)
FROM employees
WHERE job_id IS NOT NULL
GROUP BY job_id

通过上面的分析方法 , 类似的题都可以一步一步的写出来,而且能够保证错误率很少,毕竟逻辑在那里摆着了了。

上面肯定有的写的不对的地方,如果有的话,请指出,一起进步。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值