注意:MySQL中聚合函数是不能嵌套使用的
我们创建一个表t_decade_book来进行验证
DROP TABLE IF EXISTS `t_decade_book`; CREATE TABLE `t_decade_book` ( `book_id` int(10) NOT NULL AUTO_INCREMENT COMMENT '书id', `book_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '书名', `book_count` int(10) DEFAULT NULL COMMENT '数量', `detail` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '描述', PRIMARY KEY (`book_id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; INSERT INTO `t_decade_book` VALUES (1, 'Java从入门到秃头', 20, 'Java学习'); INSERT INTO `t_decade_book` VALUES (2, '数据库从删库到跑路', 20, '数据库学习'); INSERT INTO `t_decade_book` VALUES (3, '测试从入职到干架', 20, '测试脚本学习'); INSERT INTO `t_decade_book` VALUES (4, '划水越划越爽', NULL, '划水技巧学习');
得到的表数据如下
SELECT AVG(book_count),SUM(book_count),AVG(book_count)*4 FROM t_decade_book; SELECT MAX(book_count),MIN(book_count),MAX(book_name),MIN(book_name) FROM t_decade_book; SELECT COUNT(book_id),COUNT(1),COUNT(*),COUNT(book_count) FROM t_decade_book; SELECT AVG(book_count),SUM(book_count),SUM(book_count)/4,SUM(book_count)/COUNT(book_count) FROM t_decade_book;
执行结果如下
首先我们向之前创建的t_decade_blog表中插入一条数据
INSERT INTO t_decade_blog(id,name,author,create_time,views)VALUES('d3258b79-d543-49bb-9850-16cac7566666','JVM系列','十年',NOW(),8000);
表格中结果如下
然后我们测试一下GROUP BY操作
# 根据单列进行分组 SELECT author,AVG(views) FROM t_decade_blog GROUP BY author; # 根据多列进行分组,如果分组的条件相同,顺序不同不会影响最终结果 # 我们可以理解为根据这些条件进行组合,只有符合这些条件的才会分到一个组里 SELECT id,author,AVG(views) FROM t_decade_blog GROUP BY id,author; SELECT author,id,AVG(views) FROM t_decade_blog GROUP BY author,id; # 当使用GROUP BY关键字时,SELECT中涉及到的非聚合函数包含的字段,必须出现在GROUP BY后面 # 但是GROUP BY关键字后面的字段不一定要出现在SELECT之后 # 另外,在不使用GROUP BY时,聚合函数不能和普通字段放在一起进行查询 SELECT author,id,AVG(views) FROM t_decade_blog GROUP BY author; # with rollup作用在聚合函数。如果聚合函数是COUNT(*)则会在统计的记录中再次求COUNT(*) # 如果是AVG(),则会去除分组条件,求该字段的AVG() # 使用WITH ROLLUP后不能再使用ORDER BY SELECT author,AVG(views) FROM t_decade_blog GROUP BY author WITH ROLLUP; SELECT book_id,AVG(book_count) FROM t_decade_book GROUP BY book_id WITH ROLLUP; SELECT author,COUNT(views) FROM t_decade_blog GROUP BY author WITH ROLLUP;
执行结果如下
注意GROUP BY的使用顺序
1、HAVING 子句可以让我们筛选分组后的各组数据
2、HAVING和WHERE的对比
# 错误演示 SELECT id,MAX(views) FROM t_decade_blog WHERE MAX(views) > 4000 GROUP BY id; SELECT id,MAX(views) FROM t_decade_blog GROUP BY id HAVING MAX(views) > 4000; # 如果我们想查出特定博客id中最大浏览量大于4000的书籍 # 方式一:WHERE搭配HAVING,推荐此方式,执行效率更高 SELECT id,MAX(views) FROM t_decade_blog WHERE id IN ('76782763-48d0-4cef-b8e1-1054e181e41d', 'd3258b79-d543-49bb-9850-16cac7565f57', 'd3258b79-d543-49bb-9850-16cac7566666') GROUP BY id HAVING MAX(views) > 4000; # 方式二 SELECT id,MAX(views) FROM t_decade_blog GROUP BY id HAVING MAX(views) > 4000 AND id IN ('76782763-48d0-4cef-b8e1-1054e181e41d', 'd3258b79-d543-49bb-9850-16cac7565f57', 'd3258b79-d543-49bb-9850-16cac7566666');
SQL92语法结构
SELECT 字段1,字段2,...(可能存在聚合函数) FROM 表1,表2,... WHERE 多表的连接条件 AND 不包含聚合函数的过滤条件 GROUP BY 分组字段1,分组字段2... HAVING 包含聚合函数的过滤条件 ORDER BY 排序字段1,排序字段2...(ASC / DESC) LIMIT 偏移量,条目数
SQL99语法结构
SELECT 字段1,字段2,...(可能存在聚合函数) FROM 表1 (LEFT / RIGHT) JOIN 表2 ON 多表的连接条件 (LEFT / RIGHT) JOIN 表2 ON 多表的连接条件2... WHERE 不包含聚合函数的过滤条件 GROUP BY 分组字段1,分组字段2... HAVING 包含聚合函数的过滤条件 ORDER BY 排序字段1,排序字段2...(ASC / DESC) LIMIT 偏移量,条目数
我们就以SQL99语法结构为例进行分析
如有错误,欢迎指正!!!