`
蓝色飞扬
  • 浏览: 95186 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

(转)Mysql按条件计数的几种方法

 
阅读更多

Mysql按条件计数的几种方法

作者: 段 志岩
二月 25, 2011

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

问题描述

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

从前有一个皇帝,他有50个妃子,这些妃子很没有天理的给他生了100,000个儿子,于是,皇帝很苦恼,海量的儿子很难管理,而且,他想知道每个妃子给他生了多少个儿子,从而论功行赏,这很难办。于是,皇帝请了一个程序员帮他编了一个程序,用数据库来存储所有的儿子的信息,这样就可以用程序来统计和管理啦。 数据库的结构如下: id mother
皇子的唯一编号
皇子母亲的唯一编号
皇帝把妃子分成了两个等级,天宫娘娘(编号小于25)和地宫娘娘(编号大于等于25),他想知道天宫娘娘们和地宫娘娘们的生育能力孰强孰弱。于是,程序员开始写SQL Query了。

方法1:使用GROUP BY

SQL Query

 

++CoolCodeBLOCK1++

 

执行结果

  1. count(*)
  2. 50029
  3. 49971

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

分析

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

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

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

执行结果

  1. number type
  2. 50029 0
  3. 49971 1

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

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

优缺点

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

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

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

方法2:使用嵌套的SELECT

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

SQL Query

  1. SELECT 
  2.     ( SELECT COUNT( * ) FROM `prince` WHERE `mother` >24 ) AS`digong`,
  3.     ( SELECT COUNT( * ) FROM `prince` WHERE `mother` <=24 ) AS`tiangong`

执行结果

  1. digong tiangong
  2. 49971 50029

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

分析

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

优缺点

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

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

方法3:使用CASE WHEN

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

SQL Query

  1. SELECT 
  2.     COUNT( CASE WHEN `mother` >24 THEN 1 ELSE NULL END ) AS `digong`,
  3.     COUNT( CASE WHEN `mother` <=24 THEN 1 ELSE NULL END ) AS`tiangong`
  4. FROM prince

执行结果

  1. digong tiangong
  2. 49971 50029

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

分析

此方法的关键在于

  1. 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来得简单便捷。

原文地址:http://www.zhiyan.info/2011/02/24/mysql-conditional-count.html

本文短网址:http://goo.gl/344qn

分享到:
评论

相关推荐

    Mysql按条件计数多种实现方法详解

    尝试了几种方法,下面简要记录,供大家参考。 问题描述 为使讨论简单易懂,我将问题稍作简化,去掉诸多的背景。 从前有一个皇帝,他有50个妃子,这些妃子很没有天理的给他生了100,000个儿子,于是,皇帝很苦恼,...

    MYSQL获取行号row_no

    本文将详细介绍几种在MySQL中获取结果集行号的方法,并探讨它们的适用场景与局限性。 #### 方法一:使用变量自增 这种方法是通过定义一个MySQL用户变量,并利用`SELECT ... FROM`语句中的计算来实现行号的自动递增...

    mysql的myisam解决并发读写解决方法

    针对MyISAM在处理并发读写时的局限性,可以采取以下几种方法来优化性能: 1. **启用并发插入** (`concurrent_insert`) - 在MyISAM表中,可以利用`concurrent_insert`参数来允许在读操作正在进行的同时执行插入...

    mysql 查询表中多少个字段

    除了使用`INFORMATION_SCHEMA.COLUMNS`之外,还有其他几种方法可以用来查询表中的字段数量: 1. **使用`DESCRIBE`命令:** - `DESCRIBE table_name;`会列出表的所有字段及其类型、是否为空等信息。虽然这种方法不...

    Windows下mysql集群+linux下mysql集群

    虽然给定内容主要聚焦于 Windows 平台上的 MySQL 安装与配置,但构建跨平台的 MySQL 集群还需要了解 Linux 环境下的部署方法。下面简要介绍 Linux 下 MySQL 集群的配置步骤: **1. 安装 MySQL Server** - 在 ...

    Java处理Mysql.zip

    在"常用SQL语句"中,通常涉及以下几种类型: 1. **选择(SELECT)**:用于从表中检索数据。例如,`SELECT * FROM table_name` 将返回表中的所有记录。 2. **插入(INSERT)**:用于向表中插入新记录。例如,`INSERT...

    MySQL省市区脚本和json结构的数据

    MySQL数据库在IT行业中被广泛应用,尤其在存储结构化数据方面,其灵活性和高效性使得它成为许多系统的首选。本文将详细解析"MySQL省市区脚本和json结构的数据"这一主题,包括数据表的设计、SQL脚本的使用以及如何将...

    MySql培训日志_stu

    ### MySQL培训日志知识点梳理 #### 一、数据库与MySQL基础 - **1.1 数据库概述及数据准备** - **1.1.1 SQL概述** - SQL(Structured Query Language,结构化查询语言)是一种用于管理和处理数据库的标准计算机...

    mysql 判断记录是否存在方法比较

    以下是几种常用的方法,以及它们的性能比较和适用场景。 1. **使用COUNT(\*)函数** 这是最直观的方法,通过执行`SELECT COUNT(*) FROM tablename`来统计表中满足条件的记录数。如果返回的计数为0,则表示记录不...

    37-计数系统设计(一):面对海量数据的计数器要如何做?_For_group_share1

    分库分表的方法有两种常见选择:按时间分库分表和哈希分库分表。考虑到微博的访问特性,最近发布的微博计数访问量大,按时间分库会导致数据访问不均匀,最终选择了哈希分库分表,使得数据分布更均匀,提高读取性能。...

    几种数据库的数据分页

    ### 几种数据库的数据分页 #### 概述 数据分页是指在处理大量数据时,将数据分成多个页面进行展示的技术。对于大型数据库系统来说,分页不仅可以提高查询效率,还能改善用户体验。本文将详细介绍MySQL、SQL Server...

    从字符串中查找字符出现次数的方法和性能对比

    本文将深入探讨几种实现这一功能的方法,并通过实际代码示例和性能对比分析,帮助读者理解每种方法的优劣,以便在实际开发中做出更合理的选择。 ### 方法一:循环遍历法 这种方法是最直观的,也是大多数初学者接触...

    MYSQL_C_API详解1

    3. 数据类型:MYSQL_C_API提供了多种数据类型,包括MYSQL、MYSQL_RES、MYSQL_ROW、MYSQL_FIELD、MYSQL_FIELD_OFFSET等,每种类型都有其特定的作用和用途。 MYSQL_C_API的主要数据类型包括: 1. MYSQL:表示对一个...

    mysql面试题

    第三个问题是要按部门编号(Deptno)创建一个新的列并计数。这需要使用`GROUP BY`和`COUNT()`函数。示例如下: ```sql SELECT CONCAT('Deptno_', Deptno) AS Deptno_X, COUNT(*) AS cnt FROM emp GROUP BY ...

    MySQL命令大全

    MySql的用户管理是通过User表来实现的,添加新用户常用的方法有两个,一是在User表插入相应的数据行,同时设置相应的权限;二是通过GRANT命令创建具有某种权限的用户。其中GRANT的常用用法如下: grant all on mydb...

    MySQL数据库考试试题及答案.pdf

    1. 聚合函数:MySQL提供了几种聚合函数,如`MAX`(最大值)、`SUM`(求和)、`COUNT`(计数)、`AVG`(平均值)。题目中指出`SUM`用于求数据总和。 2. 游标声明:在MySQL中,声明游标使用`DECLARE CURSOR`语句。 3...

    MySQL查询语句有代码示例.txt

    本文将基于提供的文件内容,详细介绍MySQL中的几种常用查询语句及其应用场景。 #### 二、基础知识 在开始之前,我们需要了解几个基础概念: - **表**:MySQL数据库由多个表组成,每个表包含一组相关的数据。 - **...

    mysql服务器安装详解

    ### MySQL服务器安装详解 #### 一、安装准备与文件解压 MySQL是一款广泛使用的开源关系型数据库管理系统。本文档详细介绍了MySQL服务器的安装步骤。首先,下载MySQL安装包`mysql-5.0.22-win32.zip`,然后通过解压...

    MySQL安装教程图解

    - **安装选项**:向导提供了几种安装类型供选择: - **Typical(默认)**:适用于大多数情况,包含常用组件。 - **Complete(完全)**:安装所有可用组件。 - **Custom(自定义)**:允许用户选择安装哪些组件,...

Global site tag (gtag.js) - Google Analytics