基本聚集函数和case的应用

聚集函数是以一组值作为执行的输入,返回单个值函数,聚集函数也被称为组函数。聚集函数通常会和GROUP BY子句和HAVING一同使用的,SQL提供了五个固有聚集函数。

1.基本聚集函数

(1)基本聚集函数的介绍

函数作用语法
avg平均值SELECT AVG(字段名/列名) FROM 表名
min最小值SELECT MIN(column_name) FROM 表名
max最大值SELECT MAX(字段名/列名) FROM 表名
sum总和SELECT SUM(字段名/列名) FROM 表名
count计数SELECT COUNT(字段名/列名) FROM 表名

(2)使用基本聚集函数的简单例子

表结构大概就是这个样子

在这里插入图片描述


SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (
  `id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `id_card` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '身份证号码',
  `name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '姓名',
  `age` int(4) NOT NULL COMMENT '年龄',
  `city` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '城市',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '学生表' ROW_FORMAT = Compact;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, '', '小李', 9, '北京');
INSERT INTO `student` VALUES (15, '', '小李', 11, '北京');
INSERT INTO `student` VALUES (16, '', '小李', 23, '北京');
INSERT INTO `student` VALUES (17, '', '小李', 22, '北京');
INSERT INTO `student` VALUES (18, '', '小李', 18, '上海');
INSERT INTO `student` VALUES (19, '', '小李', 47, '上海');
INSERT INTO `student` VALUES (20, '', '小李', 6, '上海');
INSERT INTO `student` VALUES (21, '', '小李', 47, '上海');
INSERT INTO `student` VALUES (22, '', '小李', 16, '魔都');
INSERT INTO `student` VALUES (23, '', '小李', 19, '魔都');
INSERT INTO `student` VALUES (24, '', '小李', 21, '魔都');

SET FOREIGN_KEY_CHECKS = 1;

(1)查询最大年龄,最小年龄年龄和平均年龄

<1>最大年龄
select max(age) from student
<2>最小年龄
select min(age) from student
<3>平均年龄
select avg(age) from student

(2)配合上where语句,查询女士的平均年龄

select avg(age) from student WHERE sex = '女'

(3)多个函数的共同使用

iphone表

idnamePrice
1HuaWei6000
2XiaoMi8000
3Vivo600
4Quant9000
5NUoa1200
SELECT COUNT(*) AS nums,
MIN(Price) AS min_Price,
MAX(Price) AS max_Price,
AVG(Price) AS avg_Price,
SUM(Price) AS sum_Price 
FROM iphone

查询结果

numsmin_Pricemax_Priceavg_Pricesum_Price
56009000496024800

2.分组聚集

group by 子句作用:对给出的一个或多个属性来构造分组,将属性上取值相同的元组(数据库中的每一行就是一个元组)分到同一组中。

(1)一个简单的例子

统计学生所在城市

select city,count(*) as num from student group by city;

在这里插入图片描述


还可以在这个基础上加上一个按照性别分组的字段,如下

select sex,city,count(*) as num from student group by city,sex;

在这里插入图片描述

3.having子句

(1) where 和 having的区别

<1>group by + where 的执行流程

执行下面的语句

explain select city ,count(*) as num from student where age> 20 group by city;

在这里插入图片描述

可以发现查询条件使用了全表扫描,并且使用了临时表和排序

  1. 创建内存临时表,表里有两个字段citynum
  2. 全表扫描,找到大于年龄大于20的主键ID,找到city = ‘X’
  • 判断临时表中是否有为 city='X’的行,没有就插入一个记录 (X,1);
  • 如果临时表中有city='X’的行的行,就将x 这一行的num值加 1;
  1. 继续重复2步骤,找到所有满足条件的数据,
  2. 最后根据字段city排序,得到结果集返回给客户端。

<2>group by + having 的执行

查询居住人数大于等于4的城市名

select city ,count(*) as num from student  group by city having num >= 4;

在这里插入图片描述

having子句被称为分组过滤条件

<3>同时有where、group by 、having的执行顺序

<4>having子句和where 的区别和联系

区别:

  • 过滤对象不同
    • where后面跟的过滤对象是数据库中已经有的字段名,过滤的对象是行
    • having子句后面跟的是聚合函数,过滤的对象是是分组
  • 过滤时间不同,在sql语句中书写位置不同
    • having是在分组后对数据进行过滤
    • where是在分组前对数据进行过滤
    • having只能用在group by之后,where执行在group by之前

联系:

两者都是限定条件对数据进行筛选

<5>使用group by需要注意的问题

A.group by不一定要配合聚合函数使用

没错你没看错,group by可以不配合聚合函数使用,这在语法上是没有任何问题的,不过一般配合聚合函数使用才会有具体意义。

下面给一个不配合聚合函数使用的例子:

**注意:**不配合聚合函数使用的话,会返回每个分组中的第一行数据

select city,age from student group by  city;

在这里插入图片描述

在这里插入图片描述

B.group by后面的字段也不一定要出现在查询字段中

是的你没看错,group by后面的字段,在语法中不出现在select后面的字段中也是没问题的

来个例子来帮助理解一下吧

select id from student group by city;

在这里插入图片描述

C.分组导致的慢Sql问题

使用group by不当的话其实是容易产生慢SQL的问题的,产生这个问题的原因是因为在执行sql的过程中,用到了临时表和默认的排序,有时候甚至会遇到磁盘临时表。

  • 在执行过程中,如果达到临时表的上限后,内存临时表会转成磁盘临时表,速度就会慢下来
D.分组导致的慢Sql的优化方案
  1. 不使用磁盘临时表
  2. 不进行排序
(a)不排序
  • 给group后面的字段加索引(这样可以保证字段本身就是有序的,自然不需要排序)

  • 使用order by null

select city ,count(*) as num from student group by city order by null

(b)不使用磁盘
  • 适当调大tmp_table_size参数,这样会扩大内存临时表的容量。
  • 使用SQL_BIG_RESULT优化

在数据量过大一定会用到内存临时表时,使用SQL_BIG_RESULT 这个关键字直接用磁盘临时表

4.Sql的书写顺序和执行顺序

1.书写顺序

SELECT- DISTINCT- FROM- JOIN ON- WHERE- GROUP BY- HIVING- ORDER BY- LIMIT

distinct的含义和使用方法

作用:

distinct用来查询不重复字段值,可以使用"count(distinct city)"来返回不重复字段值的条数,distinct只能返回他的目标字段,而无法返回其他字段。

使用方法

distinct 字段名(如id)

例子
  1. 对单个字段使用
select distinct city from student

查询结果

city
北京
上海
魔都
  1. 对多个字段使用
select distinct age,city from student

查询结果

idcity
9北京
11北京
22北京
18上海
47上海
6上海
16魔都
19魔都
22魔都

2.执行顺序

FROM- ON- JOIN- WHERE- GROUP BY- HAVING- SELECT- DISTINCT- ORDER BY- LIMIT

5.CASE语句的两种形式

  • CASE 语句是 SQL 的条件判断类似于编程语言中的 if-else 语句。
  • 可以在 SELECTUPDATEDELETE 等 SQL 语句中使用,以基于不同条件返回不同的值或执行不同的操作。
  • 简单 CASE 语句
  • 搜索 CASE 语句

(1)简单CASE语句

简单CASE语句是对一个表达式的多个可能值进行比较

举个栗子

SELECT id, weekday,
    CASE weekday
        WHEN '1' THEN '周一'
        WHEN '2' THEN '周二'
        WHEN '3' THEN '周三'
				WHEN '4' THEN '周四'
				WHEN '5' THEN '周五'
        ELSE '周末'
    END AS Weekday
FROM week where id in (1,4,6);

在这里插入图片描述

(2)搜索CASE语句

举个栗子

在查询语句使用CASE

根据年龄来,对各个年龄的女性,称呼

[🐕]
SELECT id, age,
    CASE
        WHEN age <= 10 THEN '小妹妹'
        WHEN age <= 30 THEN '小姐姐'
        WHEN age >30 THEN '女士'
        ELSE '未知'
    END AS cal
FROM student 
where sex = '女'
order by age;

在这里插入图片描述

在更新语句中使用

进行动态的更新

在一个公司表中,根据销售额动态的确定员工的奖金:

  • employees 员工表
  • sales_amount 销售额
  • bonus 奖金
UPDATE employees
SET bonus = CASE
                WHEN sales_amount >= 100000 THEN 10000
                WHEN sales_amount >= 50000 THEN 5000
                ELSE 1000
            END
FROM sales
WHERE employees.emp_id = sales.emp_id;

员工按照销售额来动态的设置员工奖金

在 ORDER BY语句中使用

自定义排序

  • students 学生表
  • age 年龄
  • score 分数
SELECT * FROM students
ORDER BY 
    CASE 
        WHEN age < 18 THEN age
        WHEN age >= 18 AND score >= 90 THEN score
        ELSE name
    END
  • 首先按照年龄进行排序,年龄小于18的学生排在前面;

  • 然后按照成绩进行排序,成绩大于等于90的学生排在前面;

  • 最后按照姓名进行排序。

6.CASE 语句的注意事项

  1. 数据类型:所有的 result(就是when后面的值) 值必须是同一数据类型或可以隐式转换为同一数据类型。
  2. NULL 处理:在 CASE 语句中处理 NULL 值时,需要特别注意,因为 NULL 不等于任何值,包括它自己。可以使用 IS NULL 来检查 NULL 值。
  3. 顺序:条件的顺序很重要,因为CASE 语句会按顺序评估条件,遇到第一个为真的条件时返回相应的结果。
  • 26
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值