一天一篇mysql之九:mysql中group by关键字

Group By

Group By语句从英文的字面意义上理解就是”根据(by)一定的规则进行分组(Group)”。 
它的作用是通过一定的规则将一个数据集划分成若干个小的区域,然后针对若干个小区域进行数据处理。

group by是跟MySQL的聚合函数一起使用的,通过把一个列(column)分成组(group),来分别使用聚合函数。

  常见聚合函数:

  1. AVG() 求平均数
  2. COUNT() 求列的总数
  3. MAX() 求最大值
  4. MIN() 求最小值
  5. SUM() 求和

聚合函数特点就是它们的结果都是一个单一的值,多个行一起应用一个这样的函数后,就变成一行了。加上Group by之后,就打破了这个规则了,数据都先被group起来,然后再分别应用聚合函数;下面实操一波

1  select指定的字段要么就要包含在Group By语句的后面,作为分组的依据;要么就要被包含在聚合函数中!!!

首先创建一个toy表

create table toy (name varchar(40), version varchar(40));
insert into  toy values ('toy1','v1');
insert into  toy values ('toy1','v2');
insert into  toy values ('toy2','v1');
insert into  toy values ('toy2','v2');
insert into  toy values ('toy2','v3');
insert into  toy values ('toy3','v1');
insert into  toy values ('toy4','v2');
insert into  toy values ('toy5',null);
insert into  toy values ('toy6','v7');
insert into  toy values ('toy6','v6');
insert into  toy values ('toy6','v6');

创建后查询

然后分别查询可以看出group by的用法

select name , count(name) from toy group by name;

SELECT name,COUNT(version) from toy group by name;

select指定的字段有部分既不包含在Group By语句的后面,作为分组的依据;也没有被包含在聚合函数中!!!

重新创建一个表

CREATE TABLE `user_info` (
    `id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
    `user_id` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '用户编号',
    `grade` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '年级',
    `class` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '班级',
    PRIMARY KEY (`id`),
    UNIQUE INDEX `uniq_user_id` (`user_id`)
)
ENGINE=InnoDB

插入数据

INSERT INTO `user_info` (`user_id`, `grade`, `class`) VALUES ( '10230', 'C', 'B');
INSERT INTO `user_info` ( `user_id`, `grade`, `class`) VALUES ( '10229', 'C', 'a');
INSERT INTO `user_info` ( `user_id`, `grade`, `class`) VALUES ( '10228', 'B', 'b');
INSERT INTO `user_info` ( `user_id`, `grade`, `class`) VALUES ( '10227', 'B', 'b');
INSERT INTO `user_info` ( `user_id`, `grade`, `class`) VALUES ( '10226', 'B', 'a');
INSERT INTO `user_info` (`user_id`, `grade`, `class`) VALUES ( '10225', 'B', 'a');
INSERT INTO `user_info` ( `user_id`, `grade`, `class`) VALUES ( '10224', 'A', 'b');
INSERT INTO `user_info` ( `user_id`, `grade`, `class`) VALUES ( '10223', 'A', 'b');
INSERT INTO `user_info` (`user_id`, `grade`, `class`) VALUES ( '10222', 'A', 'a');
INSERT INTO `user_info` (`user_id`, `grade`, `class`) VALUES ( '10221', 'A', 'a');
INSERT INTO `user_info` (`user_id`, `grade`, `class`) VALUES ( '10230', 'C', null);
INSERT INTO `user_info` ( `user_id`, `grade`, `class`) VALUES ( '10229', 'C', 'a');
INSERT INTO `user_info` ( `user_id`, `grade`, `class`) VALUES ( '10228', 'B', 'b');
INSERT INTO `user_info` ( `user_id`, `grade`, `class`) VALUES ( '10227', 'B', 'b');
INSERT INTO `user_info` ( `user_id`, `grade`, `class`) VALUES ( '10226', 'B', 'a');
INSERT INTO `user_info` (`user_id`, `grade`, `class`) VALUES ( '10225', 'B', 'a');
INSERT INTO `user_info` ( `user_id`, `grade`, `class`) VALUES ( '10224', 'A', 'b');
INSERT INTO `user_info` ( `user_id`, `grade`, `class`) VALUES ( '10223', 'A', null);
INSERT INTO `user_info` (`user_id`, `grade`, `class`) VALUES ( '10222', 'A', 'a');
INSERT INTO `user_info` (`user_id`, `grade`, `class`) VALUES ( '10228', 'D', 'a');

查询可以看到


利用group by分组后

select max(user_id),grade from user_info group by grade ;
带上having
select max(user_id),grade from user_info group by grade  having grade>'A'
GROUP BY子句之后使用Having子句
可应用限定条件进行分组,以便系统仅对满足条件的组返回结果。因此,在GROUP BY子句后面包含了一个HAVING子句。HAVING类似于WHERE(唯一的差别是WHERE过滤行,HAVING过滤组)AVING支持所有WHERE操作符。

注意:::::
如果select中的字段包含了其他的字段
select max(user_id),id,grade from user_info group by grade  
这条sql的结果就值得讨论了,与上述例子不同的是,查询条件多了id一列。数据按照grade分组后,grade一列是相同的,max(user_id)按照数据进行计算也是唯一的,id一列是如何取值的?看上述的数据结果, 
推论:id是物理内存的第一个匹配项。 
修改其中一条数据
UPDATE user_info SET id=88 WHERE id=7;
再查

修改了user_id后,并没有改变查询到的数据条目,因此得出修改唯一键并不能影响查询匹配的条目规则,所以条目规则依然是匹配第一条,即id=1。

结论

  • 当group by 与聚合函数配合使用时,功能为分组后计算
  • 当group by 与having配合使用时,功能为分组后过滤
  • 当group by 与聚合函数,同时非聚合字段同时使用时,非聚合字段的取值是第一个匹配到的字段内容,即id小的条目对应的字段内容。

猜你喜欢

转载自blog.csdn.net/weixin_39666581/article/details/82228688
今日推荐