常用基础 - 统计与分组 ¶
作者:KK
发表日期:2018.8.10
要点速读 ¶
统计是通过
COUNT
函数实现的。要统计记录条数时,
COUNT(1)
比COUNT(*)
和COUNT(id)
稍微快一些,起码这是最高效的写法了。GROUP BY
分组关键字往往也是搭配着COUNT
一起来实现统计功能,比如按type
字段分组,再COUNT
统计每一个类型的记录条数。
基本统计 ¶
统计是通过COUNT
函数实现的,比如SELECT COUNT(*) AS count FROM users
就是统计 users 表有多少条记录,甚至可以SELECT COUNT(*) AS count FROM users WHERE birthday > '2000-11-11'
这样来统计符合指定条件的记录数量,那反正就是查出来的记录数量嘛,反正这个很好上手。
COUNT 指定字段 ¶
有人会写COUNT(id)
这样来直接统计 id 字段的数量来达到计数的目的,一般没问题,但千万不要随便写其它字段,因为如果这个字段的值为NULL
的时候是不会被列入计数的,如果你想要的是记录的数量,那就不要这样统计,而一般 id 字段都是主键字段,不会有NULL
的。
其实不需要COUNT(某字段)
¶
如果想要记录的数量,其实更简单的是COUNT(1)
,为什么呢?你想哦,把COUNT(id)
的时候底层还得向COUNT
函数传递id
字段的值,这就要读取id
所在的内存啦,这就产生了内存访问消耗,而COUNT(1)
的话就不需要访问什么变量的内存,直接产生一个立即数“1”传进去就行了。
其实我见过一些著名的框架在底层生成COUNT
语句的时候往往就是生成COUNT(1)
的。而效率方面嘛,跟COUNT(id)
这样统计主键差异不大,但总体还是快的,简单改一下就能快一点,何乐而不为呢?
分组统计 ¶
例如SELECT * FROM articles
查出来的数据就是所有文章,如果加上GROUP BY
关键字形成这样的语句:SELECT * FROM articles GROUP BY category_id
就是查出所有文章数据后将它们按category_id
(分类ID)进行分组,返回给你的结果就会显示每个分类只有一条记录。
没有GROUP BY
的时候,你可以认为数据列表只有一个维度,列表里就是一条条记录,可是加了GROUP BY
的时候数据就分成了2个维度,大概长这个样子(用JSON表示):
[
//分类1的列表
[
{
id: 1,
category_id: 1,
title: 文章标题,
content: 文章内容,
},
{
id: 5,
category_id: 1,
title: 文章标题,
content: 文章内容,
},
],
//分类2的列表
[
{
id: 31,
category_id: 2,
title: 文章标题,
content: 文章内容,
},
{
id: 62,
category_id: 2,
title: 文章标题,
content: 文章内容,
},
]
]
虽然是这样的形态,可是最终返回出来的时候只有一个维度的,每个分类只有1条记录给你。而实际上要这样的数据没什么用处,分组给我们带来的价值其实主要是统计,比如这样的语句:SELECT category_id, COUNT(id) FROM articles GROUP BY category_id
就统计了每个不同的分类ID分别有多少条文章记录。