pupuk / mysql

Questions & Thinking

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

MySQL Expression (MySQL 表达式)

pupuk opened this issue · comments

昨天有朋友在群里里面发了几个关于SQL查询的截图,询问其原理。

截图如下:

1
当时我也觉得有点意思,因为我们常用的 count(*) 或者 count(1)。初看了一下,觉得应该与SQL表达式的值有关系,推测了一下结果,遂在我自己常用的测试环境下,找了一张表测试了一下,得出我的猜测:
第一条语句:计算的非NULL的count值。
第二条语句:计算的release_year=2006的count值。
第三条语句:与第二条语句一样。

但是朋友问我为什么第二条语句是这样呢?我还是咯噔了一下,答不上来,装逼失败了。知其然不知其所以然了。晚上睡觉前突然浮现了这个问题,就想了一下,我的思路是,既然count()括号里面是表达式,那就从表达式入手。

比如 select release_year=2006 from film;
select release_year=2006, release_year from film; 这两条查询会是怎样的结果呢?

release_year=2006 这个地方的等号,相当于C系编程语言的 == ,判断两个值是否相等。release_year这个字段在该表有 NULL,2006,和其他值。

表格

这样一看,很简单了,select count(release_year = 2006)其实统计的就是,表达式结果为1和0的行数,也就是统计的是值为2006和其他值,也就是非NULL的值。注:count()默认是不统计NULL的。

带着这个思路,第二条语句就很好理解了。
select count(release_year = 2006 or NULL)
继续计算表达式的值,根据优先级原理,是从左到右

表格

2

所以这条语句select count(release_year = 2006 or NULL) 统计其实就是
release_year = 2006的值。
至此,第三条语句也不需要解释了。

虽然在实际项目中,我们不会这样写,为了规范,也不允许这样写。但是探究事物的本质,还是蛮有意思的。这篇文章,看似讨论的是count,其实讨论的是表达式,共勉。

今天再看时,总结了一个表格,更便于理清思路
image

  1. 表中release_year字段的值,有3种,等于2006,其他数字,NULL。
  2. release_year=2006 表达式计算的结果依次是:2006=2006的结果是1,其他数字=2006的结果是0,NULL=2006的结果是NULL,count(1)和count(0)计数,count(NULL)不计数。所以select count(release_year = 2006)统计是非NULL字段的条数。
  3. release_year=2006 or null表达式的值,是在上面的基础上,继续使用MySQL表达式
    1 or null 的结果是1
    0 or null 的结果是null
    null or null的结果是null
    所以select count(release_year=2006 or null) from film的结果是,统计release_year=2006的条数,可以在上面的表格图中看出。
  4. 最后一条带有where的语句,明显where就限制了结果集,执行where以后的结果集里面,全部都是2006,再count(release_year = 2006),其实就是count(2006=2006), 就是count(1),结果集全部计入统计。

image