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 中的 MIN
和 MAX
函数似乎可以完成您对布尔值的期望,其中 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
使用 MAX
,OR
使用 MIN
。
是的,您可能必须将参数转换为 ::integer,但这是一个很小的代价。
select min(value::integer)::boolean,
max(value::integer)::boolean,
key
from mytable
group by key;
考虑到我有一个 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 中的MIN
和 MAX
函数似乎可以完成您对布尔值的期望,其中 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
使用 MAX
,OR
使用 MIN
。
是的,您可能必须将参数转换为 ::integer,但这是一个很小的代价。
select min(value::integer)::boolean,
max(value::integer)::boolean,
key
from mytable
group by key;