为什么我们不能在不首先转换为某种整数类型的情况下在聚合函数中使用 bool 值?在许多情况下,从 bool 数据类型的列计算总和、平均值或相关性非常有意义。
考虑以下示例,其中 bool 输入必须始终转换为 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文档:
Valid literal values for the "true" state are: TRUE 't' 'true' 'y' 'yes' 'on' '1'
For the "false" state, the following values can be used: FALSE 'f' 'false' 'n' 'no' 'off' '0'
因为根据定义 TRUE
等于 1
而 FALSE
等于 0
我不明白为什么需要转换。
在聚合中允许 bool 值也会产生有趣的副作用——例如,我们可以简化许多 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;
bool 值的直接聚合(目前不工作):
select sum(gs > 50) from generate_series(1,100) gs;
是否可以在其他 DBMS 中直接聚合 bool 值?为什么这在 PostgreSQL 中是不可能的?
最佳答案
Because by definition TRUE equals 1 and FALSE equals 0 I do not understand why casting is necessary.
根据您在问题中引用的文档,根据定义, bool 值不是 1 表示真,0 表示假。在 C 中也不成立,其中 TRUE 是任何非零值。
就此而言,在这方面模仿 C 的语言也不是,有很多。它也不适用于 Ruby 等语言,其中任何非 Nil/非 False 的值都计算为 True,包括零和空字符串。它也不适用于 POSIX shell 及其变体,其中测试返回码如果为零则返回 TRUE,对于任何非零值则返回 FALSE。
重点是, bool 值就是 bool 值,从一个平台到下一个平台都有各种丰富多彩的实现细节;不是整数。
不清楚您如何期望 Postgres 计算真/假值的平均值。我怀疑许多平台是否会为此产生结果。
即使对 bool 值求和也很尴尬:期望 Postgres 对输入值进行 OR 或计算 TRUE 值吗?
无论如何,有一些 bool 聚合函数,即bool_or()
和bool_and()
。它们取代了更标准的 any()
和 some()
。 Postgres 在这里偏离标准的原因是由于潜在的歧义。根据文档:
SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...;
Here ANY can be considered either as introducing a subquery, or as being an aggregate function, if the subquery returns one row with a Boolean value.
http://www.postgresql.org/docs/current/static/functions-aggregate.html
关于database - 为什么 PostgreSQL 中的聚合函数不适用于 bool 数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20281125/