SELECT state,
COUNT(CASE WHEN elevation >= 2000 THEN 1 ELSE NULL END) as count_high_elevation_aiports
FROM airports
GROUP BY state;
在上面的陈述中,什么是THEN 1以及' 1'表示? 这个价值如何' 1'那么这会影响输出吗?
答案 0 :(得分:2)
首先,请注意这三个表达式是等效的:
CASE WHEN elevation >= 2000 THEN 1 ELSE NULL END
IF(elevation >= 2000, 1, NULL)
((elevation >= 2000) OR NULL)
如果提升> = 2000,则表达式的计算结果为“1”,否则表达式的计算结果为NULL
。
“1”通常用作布尔值true,你可以用上述表达式中的MySQL文字TRUE
替换相同的结果......但这不是“1”的用途。
与COUNT()
一起使用时,在这种情况下,1
的唯一真正意义在于它不是NULL
。
这很重要,因为 - 与普遍看法相反 - COUNT()
不计算行数。它会计算价值。
有什么区别? NULL
在技术上不是一个价值。相反,它是表示值的缺席的标记,因此COUNT(expr)
仅计算 expr 不为空的行。
通过使用类似于此处的表达式,您要求服务器使用elevation =>计算行数。 2000,你可以通过给COUNT()
一个NULL
表示你想要不计算的行...以及你做的行的非空值来实现这一点。
Aggregate (GROUP BY
) functions对值进行操作 - 而NULL
再次不是这个意义上的值。
使这个基本原理可能更加清晰的另一个聚合函数是AVG()
。如果您有3行...值为5,NULL
和10 ...平均值是多少?如果你说7.5,那是正确的:这3行的平均值是(5 + 10)÷2 = 5,因为3行只有两个值。 NULL
不为0,否则平均值为(5 + 0 + 10)÷3 = 5,而不是。
所以,这就是它的工作原理和原因。
THEN
后的值'1'如何影响输出?
它确实没有。您可以轻松地说COUNT(CASE WHEN elevation >= 2000 THEN 'cat videos are funny' ELSE NULL END)
因为,就像文字1
一样,文字字符串'cat videos are funny'
也不是空的,非空值 - 任何非空的 - 都是什么算在内。
新手可能会尝试使用COUNT(elevation >= 2000)
来完成此任务,但这会给出错误的答案,因为对于高程为< 1的行,0(false) 2000不是null,所以这些行仍然会计算在内。
然后你可以问,“为什么不用COUNT(*) ... WHERE elevation >= 2000
?”好问题。原因各不相同,但如果您GROUP BY state
并且有些行没有匹配WHERE
的行,那么这些状态将完全从结果中消除,这通常不是您想要的。此查询包含它们,计数为零。
请注意,((elevation >= 2000) OR NULL)
(顶部的第三个示例表达式)实际上不需要括号。我把它们包括在内,因为这种形式乍一看并不是必需的。如果简单地编写elevation >= 2000 OR NULL
,操作的自然优先级将导致正确评估它。此表达式与其他两个表达式相同,因为elevation >= 2000
首先计算结果为1(如果为true),0表示为false,或NULL
如果高程为空。然后评估优先级较低的OR
,您会得到其中一个:1 OR NULL => 1
... 0 OR NULL => NULL
... NULL OR NULL => NULL
...而您实际上可能会被授予当您使用COUNT(elevation >= 2000 OR NULL)
编写查询时,互联网长老会使用SQL向导徽章。
答案 1 :(得分:1)
如果elevation
为>
或=
2000,则查询只会返回 1,否则会返回 NULL
(这是用于布尔字段表示的完整,因为 NULL 表示 0 ),
现在返回的值将设置为 count_high_elevation_airports
。