最近在给某网站的后台添加一系列的统计功能,遇到很多需要按条件计数的情况。尝试了几种方法,下面简要记录,供大家参考。

问题描述

为使讨论简单易懂,我将问题稍作简化,去掉诸多的背景。

从前有一个皇帝,他有50个妃子,这些妃子很没有天理的给他生了100,000个儿子,于是,皇帝很苦恼,海量的儿子很难管理,而且,他想知道每个妃子给他生了多少个儿子,从而论功行赏,这很难办。于是,皇帝请了一个程序员帮他编了一个程序,用数据库来存储所有的儿子的信息,这样就可以用程序来统计和管理啦。

数据库的结构如下:

id

皇子的唯一编号

mother

皇子母亲的唯一编号

皇帝把妃子分成了两个等级,天宫娘娘(编号小于25)和地宫娘娘(编号大于等于25),他想知道天宫娘娘们和地宫娘娘们的生育能力孰强孰弱。于是,程序员开始写SQL Query了。

方法1:使用GROUP BY

SQL Query

SELECT COUNT(*) FROM `prince` GROUP BY `mother` > 24;

执行结果

count(*)

50029

49971

在100,000行数据上的运行时间:0.0335 秒

分析

这种GROUP BY方法的最大问题在于:无法区分所得到的结果。这两个数字哪一个是天宫娘娘们所生的皇子数,哪一个是地宫娘娘们所生的皇子数呢?不知道。所以,尽管它统计出了总数,但是没有什么意义。

因此,为了区分统计结果,必须要把条件 mother > 24 也作为一个字段在结果集中作为一个字段体现出来,修改后的sql如下:

SELECT COUNT(*) AS `number`, `mother` > 24 AS `type` FROM `prince` GROUP BY `mother` > 24;

执行结果

number type

50029 0

49971 1

条件表达式作为字段时,该字段的值就是该条件表达式的值,因此,对应我们的例子,type = 1 也就是表示 mother > 24 的值为1,因此,第二行中的数字代表地宫娘娘们所生的皇子数。

经过修改后,我们看出,天宫娘娘们略胜一筹。

优缺点

缺点是显而易见的,由于使用了条件表达式作为分组依据,它只能做二元的划分,对于要分成多类进行统计的情况不能够胜任。比如要分别统计1~10号、11~24号,25号~50号妃子的产子数,就无法实现了。

另外,由于使用了GROUP BY,因此涉及到排序,执行时间上要更长。

我暂时没有发现这种方法的优点。

方法2:使用嵌套的SELECT

使用嵌套的SELECT也可以达到目的,在每个SELECT子句中统计一个条件下的数据,然后用一个主SELECT把这些统计数据整合起来。

SQL Query

SELECT

( SELECT COUNT( * ) FROM `prince` WHERE `mother` >24 ) AS `digong`,

( SELECT COUNT( * ) FROM `prince` WHERE `mother` <=24 ) AS `tiangong`

执行结果

digong tiangong

49971 50029

在100,000行数据上的运行时间:0.0216 秒

分析

这种嵌套SELECT的方法非常直观,就是分别统计各个条件下的数值,最后进行汇总,通俗易懂,跟自然语言没啥区别了。

优缺点

优点就是直观,而且速度也比GROUP BY要快。虽然是3条SELECT语句,看起来比GROUP BY的方案多了2条语句,但是它不涉及到排序,这就节省了很多时间。

缺点可能就是语句稍多,对语句数量有洁癖的同学可能会比较不舒服。

方法3:使用CASE WHEN

CASE WHEN语句的功能很强大,可以定义灵活的查询条件,很适合进行分类统计。

SQL Query

SELECT

COUNT( CASE WHEN `mother` >24 THEN 1 ELSE NULL END ) AS `digong`,

COUNT( CASE WHEN `mother` <=24 THEN 1 ELSE NULL END ) AS `tiangong`

FROM prince

执行结果

digong tiangong

49971 50029

在100,000行数据上的运行时间:0.02365825 秒

分析

此方法的关键在于

COUNT( CASE WHEN `mother` >24 THEN 1 ELSE NULL END )

这里的COUNT和CASE WHEN联合使用,做到了分类计数。先使用CASE WHEN,当满足条件时,将字段值设置为 1, 不满足条件时,将字段值设置为NULL,接着COUNT函数仅对非NULL字段进行计数,于是,问题解决。

优缺点

优点嘛,此方法也不涉及到排序,因此运行时间上与方法2相当,SELECT语句减少到了 1 条。

缺点就是语句比较长,对语句长度有洁癖的同学可能会比较不舒服。

总结

对于确定分类的按条件计数,可以尽量不用GROUP BY,从而避免排序动作,加速Query的执行。

如果需要根据某个字段的值进行分类,而该字段的值是可变的,比如皇帝要统计每一个妃子的产子数,而他可能不停的再娶很多妃子,这种情况下,使用方法2和方法3就不太灵光了,还是使用一个GROUP BY来得简单便捷。

mysql 按照条件计数_Mysql按条件计数的几种方法相关推荐

  1. mysql添加临时索引_mysql 中添加索引的三种方法

    在mysql中有多种索引,有普通索引,全文索引,唯一索引,多列索引,小伙伴们可以通过不同的应用场景来进行索引的新建,在此列出三种新建索引的方法 mysql 中添加索引的三种方法 1.1 新建表中添加索 ...

  2. mysql如何删除数据_MySQL中删除数据的两种方法

    1. 在MySQL中有两种方法可以删除数据: 一种是delete语句,另一种是truncate table语句. delete语句可以通过where对要删除的记录进行选择,而使用truncate ta ...

  3. mysql 文件批量插入_mysql大批量插入数据的4种方法示例

    前言 本文主要给大家介绍了关于mysql大批量插入数据的4种方法,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 方法一:循环插入 这个也是最普通的方式,如果数据量不是很大,可以使用, ...

  4. mysql按某列计数_Mysql按条件计数的几种方法

    最近在给某网站的后台添加一系列的统计功能,遇到很多需要按条件计数的情况.尝试了几种方法,下面简要记录,供大家参考. 问题描述 为使讨论简单易懂,我将问题稍作简化,去掉诸多的背景. 从前有一个皇帝,他有 ...

  5. php mysql 表字段_php mysql获取表字段名称和字段信息的三种方法

    php mysql获取表字段名称和字段信息的三种方法 先给出本实例中使用的表的信息: 使用desc获取表字段信息 php代码如下: mysql_connect("localhost" ...

  6. mysql c接口返回自增id_详解mysql插入数据后返回自增ID的七种方法

    引言 mysql 和 oracle 插入的时候有一个很大的区别是: oracle 支持序列做 id: mysql 本身有一个列可以做自增长字段. mysql 在插入一条数据后,如何能获得到这个自增 i ...

  7. mysql 新增返回主键自增id_详解mysql插入数据后返回自增ID的七种方法

    引言 mysql 和 oracle 插入的时候有一个很大的区别是: oracle 支持序列做 id: mysql 本身有一个列可以做自增长字段. mysql 在插入一条数据后,如何能获得到这个自增 i ...

  8. mysql数据库最后一步卡住了_[数据库]解决MySQL安装到最后一步未响应的三种方法...

    [数据库]解决MySQL安装到最后一步未响应的三种方法 0 2018-07-13 01:01:27 这种情况一般是你以前安装过MySQL数据库服务项被占用了. 解决方法: 方法一:安装MySQL的时候 ...

  9. excel多条件计数python_Excel统计满足条件的不重复值个数的8种方法,第三种方法最适合新手!我真的入门了!...

    问题很常见,但是对新手来说又比较棘手,所以我们来一期,系统讲讲,个人我个人的知识储备,大概写了8种,涵盖Excel的方方面面!最后一种也满足一下大家对于Python的好奇! 友情提醒:应该是目前你所能 ...

  10. mysql索引命中查看_MySQL索引无法命中的几种情况及索引验证方法

    几种常见的索引不命中情况如果条件中有 or ,即使其中有条件带索引也不会命中(这也是为什么尽量少用or的原因) like查询是以%开头,如果是int型索引不会命中,字符型的命中 'test%' 百分号 ...

最新文章

  1. ci mysql 事务_MySQL事务-学习笔记
  2. linux软中断的实现
  3. Dell工作站UEFI与BIOS,AHCI与RAID模式
  4. cuda学习笔记1 - hello world实战
  5. ftp无法与服务器建立连接_建立与Oracle数据库服务器连接的两种连接模式
  6. 多数元素—leetcode169
  7. switch和if的比较
  8. JavaScript call()函数的应用
  9. 年度回顾 | 2019 年的 Apache Flink
  10. python 数据结构与算法 day04 快速排序
  11. Spark sql数据倾斜优化的一个演示案例
  12. Linux基本操作笔记
  13. 【解决idea谷歌翻译失败问题】
  14. GitHub 上最火的开源项目 —— Java 篇
  15. 非技术类:分享蓝牙音频接收器转音箱的使用
  16. python3 unicode_关于你不想知道的所有Python3 unicode特性
  17. dpdk 驱动移植叩开 kni 模块那些黑暗的角落
  18. 使用MATLAB2010实现AVI视频播放
  19. Android-布局 协调CoorinatorLayout
  20. windows下安装php环境(wampserver)

热门文章

  1. CoffeeScript 详解
  2. 【webRTC】一个基于 tornado 和 webRTC 的点对点视频语音文字聊天室
  3. 【多目标优化】3. 基于分解的多目标进化算法 —(MOEA/D)
  4. 线性可变位移传感器行业调研报告 - 市场现状分析与发展前景预测
  5. Grasshopper显示配色
  6. 苹果cms10配置本地化播放器p2p加速
  7. 理财——优质生活的第一步
  8. 台式计算机那里可以录音,录音机怎么录音?电脑录音介绍
  9. reactinput聚焦事件_React中的事件
  10. 勒索病毒基础介绍,值得收藏