Snowflake SQL 中的布尔类型是否有聚合函数 AND / OR?

Is there an aggregate function AND / OR for boolean types in Snowflake SQL?

考虑到我有一个 table 这样的

ID  X
1   TRUE
1   FALSE
2   FALSE
2   FALSE

我想实现以下结果:

ID  BOOL_OR(X)
1   TRUE
2   FALSE

也就是说,我想 GROUP BY ID 并使用布尔 OR 运算符聚合 X 的布尔值。

PostgreSQL 有 bool_or() 我可以这样使用

with t1 as
         (
             select *
             from (values (1, true)
                        , (1, false)
                        , (2, false)
                        , (2, false)) AS t1 (id, x)
         )
select id, bool_or(x)
from t1
group by id;
-- results
ID  BOOL_OR(X)
1   TRUE
2   FALSE

Snowflake SQL 中的相同查询给出 SQL compilation error: Invalid identifier BOOL_OR不足为奇,因为 Snowflake documentation for Aggregate functions 没有列出 BOOL_OR.

所以我的问题是还有其他替代方法可以获得与 PostgreSQL 的 bool_or 和 Snowflake bool_and 相同的效果 SQL?

Snowflake 中有一个 boolor() 函数,但它不是一回事。您要使用的是 Snowflake bitor_agg() 函数,它执行相同的逻辑,但在位值上。该函数有点笨拙,因为它使用了布尔值的整数等效值,而不是直接使用布尔值。因此,在您的示例中:

with t1 as
         (
             select  as id,  as x
             from (values (1, true)
                        , (1, false)
                        , (2, false)
                        , (2, false)) AS t1
         )
select id, bitor_agg(x::integer)::boolean
from t1
group by id;

函数内部的转换使 bitor_agg() 函数的值变为整数,然后外部的布尔转换为您将其恢复为布尔值。

https://docs.snowflake.net/manuals/sql-reference/functions/bitor_agg.html

更新 2019-11-04

Snowflake 最近引入了 BOOLOR_AGG and BOOLAND_AGG 函数,应该可以提供所需的功能。

原回答

Snowflake 中的

MINMAX 函数似乎可以完成您对布尔值的期望,其中 MIN 的工作方式与 BOOL_AND / AND_AGG 类似,而 MAX 的工作方式像 BOOL_OR / OR_AGG.

看这个例子:

create or replace table x(col1 boolean, col2 boolean, col3 boolean);
insert into x values(true, true, false),(true,false,false);
select * from x;
------+-------+-------+
 COL1 | COL2  | COL3  |
------+-------+-------+
 TRUE | TRUE  | FALSE |
 TRUE | FALSE | FALSE |
------+-------+-------+

select min(col1),max(col1),min(col2),max(col2),min(col3),max(col3) from x;
-----------+-----------+-----------+-----------+-----------+-----------+
 MIN(COL1) | MAX(COL1) | MIN(COL2) | MAX(COL2) | MIN(COL3) | MAX(COL3) |
-----------+-----------+-----------+-----------+-----------+-----------+
 TRUE      | TRUE      | FALSE     | TRUE      | FALSE     | FALSE     |
-----------+-----------+-----------+-----------+-----------+-----------+

请注意,这似乎没有正式记录,因此使用风险自负:)

我打算提出一些更简单的建议: AND 使用 MAXOR 使用 MIN。 是的,您可能必须将参数转换为 ::integer,但这是一个很小的代价。

select   min(value::integer)::boolean,
         max(value::integer)::boolean,
         key
from     mytable
group by key;