视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
mysql查询嵌套
2020-11-09 14:04:01 责编:小采
文档


方法1:使用GROUP BY

SQL Query

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

执行结果

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

下载本文
显示全文
专题