13、group by分组

group by 分组

  • GROUP BY 语句根据一个或多个列对结果集进行分组。
  • 在分组的列上我们可以使用 COUNT, SUM, AVG,等函数。

1、max 、min 、sum 、avg 、count 使用

类型 宽度 实例
max 最大值 select max(shop_price) from goods;
min 最小值 select min(shop_price) from goods;
sum 求总和 select sum(good_number) from goods;
avg 求平均 select avg(shop_price) from goods;
count 求总行数 select count(*) from goods;

实现了:

  • 查出最贵的商品
  • 查出最便宜的商品
  • 查出平均价
  • 查询一共有多少种商品,即是求表中有多少行,其中*可以为1,0,及其其他的任意有效字段。

1.1 count 详解

  • count(*)中星号表示任意字段,表示每次数该字段,一共数多少次,当星号用有效字段名替代,且表中有null的时候,数的次数并不是行数,建议直接用星号表示
  • select count(*) from 表名; 查询的就是绝对的行数,哪怕某一行所有字段全为NULL,也计算在内。
  • select count(列名) from 表名; 查询的是该列不为NULL的行数
  • 用count(*),count(1)谁好呢?

    对于myisam引擎的表没有区别,这种引擎内部有一个计数器在维护者行数
    Innodb的表,用count(*)直接读行数,效率很低,因为innodb真的要去数一遍。

代码

create table test8(
id int,
name varchar(20)
)engine myisam charset=utf8;

insert into test8 values (1,‘lisi‘);
insert into test8 values (2,null);

mysql> select count(*) from test8;
+----------+
| count(*) |
+----------+
|        2 |
+----------+
1 row in set

mysql> select count(name) from test8;
+-------------+
| count(name) |
+-------------+
|           1 |
+-------------+
1 row in set

2、函数与where结合使用

建表

DROP TABLE IF EXISTS `employee_tbl`;
CREATE TABLE `employee_tbl` (
  `id` int(11) NOT NULL,
  `name` char(10) NOT NULL DEFAULT ‘‘,
  `date` datetime NOT NULL,
  `singin` tinyint(4) NOT NULL DEFAULT ‘0‘ COMMENT ‘登录次数‘,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

添加数据

INSERT INTO `employee_tbl` VALUES (‘1‘, ‘小明‘, ‘2016-04-22 15:25:33‘, ‘1‘),
(‘2‘, ‘小王‘, ‘2016-04-20 15:25:47‘, ‘3‘), (‘3‘, ‘小丽‘, ‘2016-04-19 15:26:02‘, ‘2‘),
(‘4‘, ‘小王‘, ‘2016-04-07 15:26:14‘, ‘4‘), (‘5‘, ‘小明‘, ‘2016-04-11 15:26:40‘, ‘4‘),
(‘6‘, ‘小明‘, ‘2016-04-04 15:26:54‘, ‘2‘);
COMMIT;

mysql> select * from employee_tbl;
+----+------+---------------------+--------+
| id | name | date                | singin |
+----+------+---------------------+--------+
|  1 | 小明 | 2016-04-22 15:25:33 |      1 |
|  2 | 小王 | 2016-04-20 15:25:47 |      3 |
|  3 | 小丽 | 2016-04-19 15:26:02 |      2 |
|  4 | 小王 | 2016-04-07 15:26:14 |      4 |
|  5 | 小明 | 2016-04-11 15:26:40 |      4 |
|  6 | 小明 | 2016-04-04 15:26:54 |      2 |
+----+------+---------------------+--------+
6 rows in set

count 与 where 结合,计算小明出现的次数
select count(*) from employee_tbl where name=‘小明‘;

问题:
我们能知道,小明出现的次数,也能知道小王出现的次数,但是如何一次查询他们各自出现的次数呢?

3、GROUP BY 语法

SELECT column_name, function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name;

3.1、group by 实例

查询小明、小王、小丽个自登录的次数,意味者需要根据名字分组

mysql> select name, sum(singin) from employee_tbl group by name;
+------+-------------+
| name | sum(singin) |
+------+-------------+
| 小明 | 7           |
| 小王 | 7           |
| 小丽 | 2           |
+------+-------------+
3 rows in set

3.2、使用 with rollup

  • WITH ROLLUP 可以实现在分组统计数据基础上再进行相同的统计(SUM,AVG,COUNT…)。

例如我们将以上的数据表按名字进行分组,再统计每个人登录的次数:

mysql> SELECT name, SUM(singin) as singin_count FROM  employee_tbl GROUP BY name WITH ROLLUP;
+------+--------------+
| name | singin_count |
+------+--------------+
| 小丽 | 2            |
| 小明 | 7            |
| 小王 | 7            |
| NULL | 16           |
+------+--------------+
4 rows in set

其中记录 NULL 表示所有人的登录次数。 我们可以使用 coalesce 来设置一个可以取代 NUll 的名称,coalesce 语法:

select coalesce(a,b,c);

参数说明:如果a==null,则选择b;如果b==null,则选择c;如果a!=null,则选择a;如果a b c 都为null ,则返回为null(没意义)。

以下实例中如果名字为空我们使用总数代替:

mysql> SELECT coalesce(name, ‘总数‘), SUM(singin) as singin_count FROM  employee_tbl GROUP BY name WITH ROLLUP;
+--------------------------+--------------+
| coalesce(name, ‘总数‘) | singin_count |
+--------------------------+--------------+
| 小丽                   |            2 |
| 小明                   |            7 |
| 小王                   |            7 |
| 总数                   |           16 |
+--------------------------+--------------+
4 rows in set (0.01 sec)

4、易错语句判断

4.1 select name, sum(singin) from employee_tbl;

显示:1140 - In aggregated query without GROUP BY...
name 与 sum(singin) 不匹配。

改正:select name, sum(singin) from employee_tbl group by name;

严格的讲,select的a,d列必须在group by 的 a,b,c 列里出现
也就是说,以group by a,b,c 为列,则select的列,只能在a,b,c里选择语义上才没有矛盾。

原文地址:https://www.cnblogs.com/Stephanie-boke/p/11664536.html

时间: 2024-10-13 17:00:08

13、group by分组的相关文章

sql分别用日期、月、年 分组 group by 分组,datepart函数

标签: datepart函数sql分别用日期月年 分组group by 分组 2013-12-26 15:31 20764人阅读 评论(1) 收藏 举报 分类: SQL Server(21) 版权声明:本文为博主原创文章,未经博主允许不得转载. [sql] view plain copy --以2013-12-10 12:56:55为例 --convert(nvarchar(10),CreateDate,120) => 2013-12-10 --DATEPART(month,CreateDate

单表查询: where group by 分组 having distinct 去重 order by 排序 limit 多表查询 子查询 连表查询

今日内容 表查询 单表查询: where group by 分组 having distinct 去重 order by 排序 limit 多表查询 子查询 连表查询 单表查询 前期表准备 create table emp( id int not null unique auto_increment, name varchar(20) not null, sex enum('male','female') not null default 'male', #大部分是男的 age int(3) u

数据库开发基础-教案-4-聚合函数、group by分组的使用方法、数学函数

聚合函数:sum,avg,max,min,count 使用方法示例: group by  分组的使用方法 分组的练习: 数学函数:ABS.ceiling.floor.power.round.sqrt.square 数据库的简单查询练习:

mysql使用GROUP BY分组实现取前N条记录的方法

MySQL中GROUP BY分组取前N条记录实现 mysql分组,取记录 GROUP BY之后如何取每组的前两位下面我来讲述mysql中GROUP BY分组取前N条记录实现方法. 这是测试表(也不知道怎么想的,当时表名直接敲了个aa,汗~~~~): 结果: 方法一: SELECT a.id,a.SName,a.ClsNo,a.Score FROM aa a LEFT JOIN aa b ON a.ClsNo=b.ClsNo AND a.Score<b.Score group by a.id,a.

浅析MySQL使用 GROUP BY 分组聚合与细分聚合

1. 聚合函数(Aggregate Function) MySQL(5.7 ) 官方文档中给出的聚合函数列表(图片)如下: 详情点击https://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html . 除非另有说明,否则聚合函数都会忽略空值(NULL values). 2. 聚合函数的使用 聚合函数通常对 GROUP BY 语句进行分组后的每个分组起作用,即,如果在查询语句中不使用 GROUP BY 对结果集分组,则聚合函数就对结果集

Group by 分组查询 实战

实战经历,由于本人在共享单车上班,我们的单车管理模块,可以根据单车号查询单车,但是单车号没有设置unique(独一无二约束),说以这就增加了单车号可能重复的风险,但是一般情况下,单车号是不会重复的,因为平台的单车都是人工录入的,但是二般情况下,就会出现,一旦出现,那么就shit了,很不幸,今天就出现了这个问题,“一个单车号,可以在单车管理模块查出来有两条记录”这个时候,我们就必须把出现这种问题的单车号,再次手动编辑改变,由于数据库里,单车管理表里有成千上万个单车,但是,都有哪一个单车号出现了两次

Oracle SQL篇(四)group by 分组与分组的加强 rollup

    分组操作group by 和分组的强化(rollup) 分组操作和分组函数的使用,对于编写SQL语句的人来说,是最基本的概念. 我们来看下面的例子: 在这里我们使用员工表EMP [email protected]> select * from emp; EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO ---------- ---------- ------

Linq DataTable Group By 分组显示人员明细

原始数据: 分组后的输出结果: 源代码: 1 public static void PrintPersons() 2 { 3 //准备数据 4 DataTable dt = new DataTable(); 5 dt.Columns.Add(new DataColumn("ID", typeof(int))); 6 dt.Columns.Add(new DataColumn("UserName", typeof(string))); 7 dt.Columns.Add

关于MYSQL group by 分组按时间取最大值的实现方法!

类如 有一个帖子的回复表,posts( id , tid , subject , message , dateline ) , id 为 自动增长字段, tid为该回复的主题帖子的id(外键关联), subject 为回复标题, message 为回复内容, dateline 为回复时间,用UNIX 时间戳表示, 现在要求 选出 前十个来自不同主题的最新回复 SELECT * FROM posts GROUP BY tid LIMIT 10 这样一个sql语句选出来的并非你想要的 最新的回复,而