为什么在不首先转换为某种整数类型的情况下不能在聚合函数中使用布尔值?在许多情况下,从布尔数据类型的列中计算总和,平均值或相关性是很有意义的。
考虑以下示例,必须始终将布尔输入强制转换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文档中:
“ true”状态的有效文字值是:TRUE't''true''y''yes''on''1'
对于“ false”状态,可以使用以下值: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的语言也不是,C语言有很多。对于诸如Ruby之类的语言也不是,其中任何非Nil / non-False的值都等于True,包括零和空字符串。POSIX shell及其变体也没有,如果返回码为零,则测试返回码将生成TRUE,否则返回FALSE。
重点是,布尔值是布尔值,具有从平台到下一个平台的各种丰富多彩的实现细节。不是整数。
目前尚不清楚您对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
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句