为什么我们不能在聚合函数中使用布尔值而不首先转换为某种整数类型?在许多情况下,从布尔数据类型的列计算总和,平均值或相关性是完全合理的.
请考虑以下示例,其中必须始终将boolean输入转换int
为使其工作:
select sum(boolinput::int), avg(boolinput::int), max(boolinput::int), min(boolinput::int), stddev(boolinput::int), corr(boolinput::int,boolinputb::int) from (select (random() > .5)::boolean as boolinput, (random() > .5)::boolean as boolinputB from generate_series(1,100) ) a
从PostgreSQL文档:
"真实"状态的有效字面值为:"1"上的"真","是","是"
对于"假"状态,可以使用以下值:FALSE'f''false''n''no''off''0'
因为根据定义TRUE
等于1
和FALSE
等于0
我不明白为什么铸造是必要的.
在聚合中允许布尔值也会产生有趣的副作用 - 例如,我们可以简化许多case语句:
当前版本(干净且易于理解):
select sum(case when gs > 50 then 1 else 0 end) from generate_series(1,100) gs;
使用老式铸造操作员::
:
select sum((gs > 50)::int) from generate_series(1,100) gs;
直接聚合布尔值(当前不工作):
select sum(gs > 50) from generate_series(1,100) gs;
是否可以在其他DBMS中直接聚合布尔值?为什么在PostgreSQL中无法做到这一点?
因为根据定义TRUE等于1而FALSE等于0我不明白为什么需要施法.
根据您在问题中引用的文档,根据定义,布尔值不是1表示TRUE,0表示FALSE.在C中也不是这样,其中TRUE是非零的.
就此而言,也不是在这方面模仿C的语言,其中有很多.也不是像Ruby这样的语言,其中任何非Nil/non-False评估为True,包括零和空字符串.它也不适用于POSIX shell及其变体,其中测试返回码如果为零则产生TRUE,而对于任何非零值则产生FALSE.
Point是,布尔值是一个布尔值,具有从平台到下一个平台的各种丰富的实现细节; 不是整数.
目前还不清楚你是如何期待Postgres平均真假值的.我怀疑许多平台是否会产生结果.
即使总结布尔值也很尴尬:期望Postgres输入OR值,还是计算TRUE值?
无论如何,有一些布尔聚合函数,即bool_or()
和bool_and()
.这些取代了更多的标准any()
和some()
.Postgres偏离标准的原因是由于潜在的模糊性.根据文档:
SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...;
如果子查询返回带有布尔值的行,则可以将ANY视为引入子查询或者作为聚合函数.
http://www.postgresql.org/docs/current/static/functions-aggregate.html