将MIN聚合函数应用于BIT字段
我想写下面的查询:
SELECT ..., MIN(SomeBitField), ... FROM ... WHERE ... GROUP BY ...
问题是, SQL Server不喜欢它,当我想计算一个位字段的最小值时,它返回错误Operand data type bit is invalid for min operator
。
我可以使用以下解决方法:
SELECT ..., CAST(MIN(CAST(SomeBitField AS INT)) AS BIT), ... FROM ... WHERE ... GROUP BY ...
但是,有没有更优雅的东西? (例如,可能有一个我不知道的聚合函数,它计算字段中的逻辑值and
位值。)
由于BIT
只有两个选项,只需使用一个case语句:
SELECT CASE WHEN EXISTS (SELECT 1 FROM ....) THEN 1 ELSE 0 END AS 'MinBit' FROM ... WHERE ...
这具有以下优点:
- 不强制表扫描(
BIT
字段上的索引几乎不会被使用) - 短路TWICE(一次用于
EXISTS
,再用于CASE
)
这是一个更多的代码,但它不应该是可怕的。 如果您有多个值来检查,您可以始终在查询开始处将更大的结果集(包括所有JOIN
和FILTER
条件)封装在CTE
中,然后在CASE
语句中引用该值。
一个选项是MIN(SomeBitField+0)
。 它读得很好,噪音较小(我认为这是优雅的)。
这就是说,它比CASE
选项更为黑客。 而且我对速度/效率一无所知。
尝试以下注意:最小代表和聚合函数,最大代表或聚合函数
SELECT ..., MIN(case when SomeBitField=1 then 1 else 0 end), MIN(SomeBitField+0)... FROM ... WHERE ... GROUP BY ...
同样的结果
这个查询是最好的解决scheme:
SELECT CASE WHEN MIN(BitField+0) = 1 THEN 'True' ELSE 'False' END AS MyColumn FROM MyTable
当你添加BitField + 0时,它会自动变成int
select min(convert(int, somebitfield))
或者如果你想保持一点点的结果
select convert(bit, min(convert(int, somebitfield)))
AVG(CAST(boolean_column AS FLOAT))OVER(…)AS BOOLEAN_AGGREGATE
给一个模糊的布尔值:
-
1表示全部为真;
-
0表示全是假的;
-
一个介于0..1之间的值[表示部分匹配,并且可以是真值的某个百分比。