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