常用基础 - 统计与分组

  • 作者:KK

  • 发表日期:2018.8.10


要点速读

  1. 统计是通过COUNT函数实现的。

  2. 要统计记录条数时,COUNT(1)COUNT(*)COUNT(id)稍微快一些,起码这是最高效的写法了。

  3. 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分别有多少条文章记录。