数据库之--count/distinct/group by的用法总结

一、 count、distinct、group by的用法:

1.count()函数是用来统计表中记录的一个函数,返回匹配条件的行数,不去重。

2.count()语法:

(1)count(*)---包括所有列,返回表中的记录数,相当于统计表的行数,在统计结果的时候,包含NULL的记录,且不去重

(2)count(1)---第一列,1表示一个固定值,也可以用count(2)、count(3)代替,在统计结果的时候,包含NULL的记录。

(3)count(列名)---只包括列名指定列,返回指定列的非空的记录数,在统计结果的时候,不包含为NULL的记录。

(4)count(distinct 列名)---只包括列名指定列,返回指定列的不同值的记录数,即会去重,且不包含列值为NULL的记录。

3.  SELECT count(*) FROM 表名 WHERE 条件 // 这样查出来的是总记录条

SELECT  id  count(*)FROM 表名 WHERE 条件 GROUP BY id //这样统计的会是每组的记录条数,统计出来的是相同id值的计数情况。

SELECT  id  count(*) FROM 表名 WHERE 条件. 是错误的写法。

 

一般来说,一条select语句的执行顺序如下:from子句→where→group by(having)→select→order by→limit,因为聚集函数是在select中的,所以是在执行完group by之后再执行count()函数,

 

转载地址:https://blog.csdn.net/wuyou1336/article/details/53822745 

本文将探讨以下问题

1.count(*) count(n)count(null)count(fieldName)
2.distinct
count 连用
3.group by (
多个字段) count 实现分组计数

 准备表以及数据

[sql] view plain copy

-- 创建表  

CREATE TABLE `tb_student` (  

 `id` int(11) NOT NULL,  

 `stu_name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '学生姓名',  

`tea_name` varchar(255) DEFAULT NULL COMMENT '教师姓名',  

  `stu_class` varchar(255) DEFAULT NULL COMMENT '所在班级名称',  

  `stu_sex` varchar(255) DEFAULT NULL COMMENT '学生性别',  

  `stu_sex_int` tinyint(4) DEFAULT NULL,  

  PRIMARY KEY (`id`)  

  1. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;  
  2. -- 插入数据   

INSERT INTO `tb_student` (`id`, `stu_name`, `tea_name`, `stu_class`, `stu_sex`) VALUES ('0', '小明', '老张', '一班', '男',0);  

INSERT INTO `tb_student` (`id`, `stu_name`, `tea_name`, `stu_class`, `stu_sex`) VALUES ('1', '小红', '老张', '一班', '女',0);  

INSERT INTO `tb_student` (`id`, `stu_name`, `tea_name`, `stu_class`, `stu_sex`) VALUES ('2', '小刚', '老王', '一班', '男',0);  

INSERT INTO `tb_student` (`id`, `stu_name`, `tea_name`, `stu_class`, `stu_sex`) VALUES ('3', '小兰', '老王', '一班', '女',0);  

INSERT INTO `tb_student` (`id`, `stu_name`, `tea_name`, `stu_class`, `stu_sex`) VALUES ('4', '小军', '老张', '二班', '男',0);  

INSERT INTO `tb_student` (`id`, `stu_name`, `tea_name`, `stu_class`, `stu_sex`) VALUES ('5', '小芳', '老张', '二班', '女',0);  

INSERT INTO `tb_student` (`id`, `stu_name`, `tea_name`, `stu_class`, `stu_sex`) VALUES ('6', '小强', '老王', '二班', '男',0);  

INSERT INTO `tb_student` (`id`, `stu_name`, `tea_name`, `stu_class`, `stu_sex`) VALUES ('7', '小娜', '老王', '二班', '女',0);  

INSERT INTO `tb_student` (`id`, `stu_name`, `tea_name`, `stu_class`, `stu_sex`) VALUES ('8', null, null, null, null,null);  

问题一:count(*) count(n)count(null)count(fieldName)

我们看一下执行过程:
EXPLAIN SELECT count(0)from tb_student
EXPLAIN SELECT count(*)from tb_student
两次执行结果相同,结果为
(select_type, table, type,possible_keys, key, key_len, ref, rows, Extra) VALUES ('1', 'SIMPLE','tb_student', 'index', NULL, 'stu_sex_int', '2', NULL, '8', 'Using index'); 
此次查询使用了索引stu_sex_int。我们知道某个字段建立索引之后数据库引擎会对该字段排序并把排序结果作为索引数据存储。查询时候对索引进行
二分查找提高命中率。在使用聚集函数同样也会使用索引。数据库引擎在处理count,直接从索引数据(排序结果中)中求排序结果的id最大值。这样一来会大大提高count的速度。主键也有索引此处为什么没有使用主键的索引?因为stu_sex_int 字段长度更短tinyint 类型,查找速度更快。
由此可见 count(*)count(n) n>=0 的效果相同。
count的表达式为 NULL 不会计数 ,所以count(fieldName)fieldName null不会计数。比如

·       select count(stu_name) as count from tb_student; 结果: count=8

·       select count(id) as count from tb_student; 结果: count=9

·       select count(null) as count from tb_student ; 结果: count= 0

问题二: distinct count 连用

distinct 的作用是对查询结果去重distinctfieldA 那么在查询结果中 fieldA 的值不会重复。当 count 内的表达式是distinct时候,所表达的意思就是对被distinct的字段取值类型计。例如:

select distinct stu_class from tb_student;

执行结果:

stu_class

一班

二班

select count(distinct stu_class) as count fromtb_student;
执行结果:

count

2

问题三:group by (多个字段) count 实现分组计数

group by fieldA 是表示根据 fieldA 的不同取值对查询结果进行分组。比如对于 tb_student 表,根据 stu_sex 的不同取值 (,) 可把查询结果分成两组。fieldA n个不同的取值,查询结果就会被分成n组。

当分组字段有多个时候group by fieldA,fieldB 会对fieldA fieldB 进行排列组合。每个排列组合的,结果作为查询一个的一个分组。如果fileA 的取值有 n  fieldB的取值有 m 个,那么查询结果将会被分称m*n组。

count group by 连用时,count是对 group by 结果的各个分组进行计数

单个分组条件:
SELECT stu_sex ,COUNT(*) ascount from tb_student GROUP BY stu_sex ;
结果为:

stu_sex

count

NULL

1

4

4

多个分组条件:

    SELECT
        stu_sex,
        stu_class,
        COUNT(*) AScount
    FROM
        tb_student
    GROUPBY
        stu_sex,
        stu_class

结果为:

stu_sex

stu_class

count

NULL

NULL

1

一班

2

二班

2

一班

2

二班

2

COUNT(*)通常是对主键进行索引扫描,而COUNT(COL)就不一定了,另外前者是统计表中的所有符合的纪录总数,而后者是计算表中所有符合的COL的纪录数。还有有区别的。

COUNT的时候,如果没有WHERE限制的话,MySQL直接返回保存有总的行数,而在有WHERE限制的情况下,总是需要对MySQL进行全表遍历。

具有GROUP BY的MySQL COUNT

我们经常将COUNT函数与GROUP BY子句结合使用来统计不同分组中的数据。请参见以下products表的结构

mysql> desc products;
+--------------------+---------------+------+-----+---------+------------------+
| Field              | Type          | Null | Key | Default | Extra            |
+--------------------+---------------+------+-----+---------+------------------+
| productCode        | varchar(15)   | NO   | PRI |         |                  |
| productName        | varchar(70)   | NO   | MUL | NULL    |                  |
| productLine        | varchar(50)   | NO   | MUL | NULL    |                  |
| productScale       | varchar(10)   | NO   |     | NULL    |                  |
| productVendor      | varchar(50)   | NO   |     | NULL    |                  |
| productDescription | text          | NO   |     | NULL    |                  |
| quantityInStock    | smallint(6)   | NO   |     | NULL    |                  |
| buyPrice           | decimal(10,2) | NO   |     | NULL    |                  |
| MSRP               | decimal(10,2) | NO   |     | NULL    |                  |
| stockValue         | double        | YES  |     | NULL    | STORED GENERATED |
+--------------------+---------------+------+-----+---------+------------------+
10 rows in set
SQL

例如,要查找每个产品系列中的产品数量,可以使用COUNT函数与GROUP BY子句,如下查询所示:

SELECT productline, count(*) FROM products GROUP BY productline;
SQL

执行上面代码,得到以下结果 -

mysql> SELECT productline, count(*) FROM products GROUP BY productline;
+------------------+----------+
| productline      | count(*) |
+------------------+----------+
| Classic Cars     |       38 |
| Motorcycles      |       13 |
| Planes           |       12 |
| Ships            |        9 |
| Trains           |        3 |
| Trucks and Buses |       11 |
| Vintage Cars     |       24 |
+------------------+----------+
7 rows in set
Shell

要查找供应商提供的产品数量,请使用以下查询:

SELECT productvendor, count(*) FROM products GROUP BY productvendor;
SQL

执行上面代码,得到以下结果 -

mysql> SELECT productvendor, count(*) FROM products GROUP BY productvendor;
+---------------------------+----------+
| productvendor             | count(*) |
+---------------------------+----------+
| Autoart Studio Design     |        8 |
| Carousel DieCast Legends  |        9 |
| Classic Metal Creations   |       10 |
| Exoto Designs             |        9 |
| Gearbox Collectibles      |        9 |
| Highway 66 Mini Classics  |        9 |
| Min Lin Diecast           |        8 |
| Motor City Art Classics   |        9 |
| Red Start Diecast         |        7 |
| Second Gear Diecast       |        8 |
| Studio M Art Models       |        8 |
| Unimax Art Galleries      |        8 |
| Welly Diecast Productions |        8 |
+---------------------------+----------+
13 rows in set
Shell

要查找哪个供应商提供至少9个产品,您可以使用HAVING子句在COUNT函数中,如以下查询语句所示:

SELECT productvendor, count(*) FROM products GROUP BY productvendor
HAVINGcount(*)>=9;
SQL

执行上面代码,得到以下结果 -

mysql> SELECT productvendor, count(*) FROM products GROUP BY productvendor
HAVING count(*) >= 9;
+--------------------------+----------+
| productvendor            | count(*) |
+--------------------------+----------+
| Carousel DieCast Legends |        9 |
| Classic Metal Creations  |       10 |
| Exoto Designs            |        9 |
| Gearbox Collectibles     |        9 |
| Highway 66 Mini Classics |        9 |
| Motor City Art Classics  |        9 |
+--------------------------+----------+
6    rows in set

 

实例练习:

1、主人的数量:

select count(owner) from pet;

错误的写法:SELECT  owner, COUNT(*) FROM pet;

2、每个主人拥有的宠物总量:

select owner count(*) from pet group by owner;

3、每种动物的数量:

select species count(*) from pet group by species;

4、每种性别的动物数:

select sex count(*) from petgroup by sex

5、按种类和性别组合的动物数

select species,sex,count(*) from pet group by species,sex;

6、只对狗和猫进行查询统计时:

Select species,sex,count(*) from pet

where  species=’dog’ or species=’cat’

group by species,sex;

7、统计已知性别的动物的数量

Select sex count(sex) from pet

Where sex is not null

Group by sex;

8, Distinct的用法

① 去重,比如:selectcount(distinct id) from pet

是计算不同id的宠物id的个数

② 要返回不同id的具体值的时候:

Select distinct idfrom pet;

返回不同id的宠物的具体值

4、去重:SELECT DISTINCT 列名称 FROM 表名称

select distinct salary from salaries

where salary.to_date='9999-01-01'

order by salaries.salary desc;

或者:group by

select salary from salarieswhere to_date='9999-01-01'

group by salary

order by salary desc;

 

 

二、  group by 与order by

group  by:从英文上理解就是分组的意思。需要和聚合函数(例如:max(),count(),avg()等)配合使用,使用时至少有一个分组标识字段(例如某一列的列名)。

order  by :从英文上理解就是排序。一般后面跟上某一列的列名,然后查询到的数据会以该列的大小顺序进行排序显示,默认的是ASC(从小到大排列),desc(大到小排列)

where: 对查询到的内容进行筛选,where后面跟上限定条件,where使用在分组和排序之后。

having:作用是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数,使用having 条件显示特定的组,也可以使用多个分组标准进行分组。

group by按照查询结果集中的某一列(或多列),进行分组,值相等的为一组。

1)细化集函数(count,sum,avg,max,min)的作用对象:

未对查询结果分组,集函数将作用于整个查询结果。

对查询结果分组后,集函数将分别作用于每个组。例如:

Selsct deptmax(salary) as maxmum

from staff

Group by dept;

统计结果为每个部门的薪水最高值。

2)按时间顺序排列:

select * from staff

   Order by hiredate;

3)只展示开发部的信息

   Select * from staff

   Where dept = ‘开发部’

4)筛选出分组后的max大于3000的一组

Select dept, max(salary) as maxmum

from staff

Group by dept

Having max(salary)>3000;

5)倒序显示日期大于 2010-10-03中,每个部门中工资最高且大于2000的数据

Select deptmax(salary)  as  maxmum from  satff

Wherehiredate>’2010-10-03’

Group  by dept  having max(salary)>2000

Order by maxmum desc;

6) 查询公司2010年入职的各个部门每个级别里的最高薪水

Select dept,level,max(salary) as maxmum from staff

Where hiredate>=2010-01-01

Group by dept,level

7) 查找雇员数超过2个的部门的最高和最低薪水:

Select dept,count(*),max(salary) as maxmum,min(salary) as minmum

from staff

Group by dept

Having count(*)>2

 

8) 查找雇员平均工资大于3000的部门的最高薪水和最低薪水:

Select dept,max(salary) as maxmum,min(salary) as minmum

From staff

Group by dept

having avg(salary)>3000

猜你喜欢

转载自blog.csdn.net/byf0521hlyp/article/details/80224840