如何将 SUM 用于位列?

Posted

技术标签:

【中文标题】如何将 SUM 用于位列?【英文标题】:How can I use SUM for bit columns? 【发布时间】:2016-02-29 13:07:43 【问题描述】:

T-SQL中位列如何使用函数SUM()?

当我尝试如下操作时:

SELECT SUM(bitColumn) FROM MyTable;

我得到错误:

求和运算符的操作数数据类型位无效。

【问题讨论】:

这取决于您认为位列的总和应该是什么意思。 SQL Server 不允许这样做,因为它不明确,因为位列通常是布尔值或位掩码。这就像问“Add(True,False) 的价值是什么?”那么,Add() 是 AND 函数还是 OR 函数? 这只是将结果组合在一起的一种方式。在我的场景中,一条记录的 bitColumn 为 True,而其他记录的 bitColumn 为 False,但我不希望分组因此而丢失。所以我对“位”列求和,如果 SUM 大于 0,我很感兴趣。 @BaconBits ADD 通常转换为 OR,MULTIPLY 转换为 AND,因为它们遵循相似的规律 @ArturoTorresSánchez 这是因为逻辑门就是这样工作的,其中 AND 是乘法,XOR 是加法,而不是因为这是对 SUM( <Boolean values> ) 的唯一有意义的解释。要求SUM()的具体实现肯定不够清楚。 【参考方案1】:
SELECT SUM(CAST(bitColumn AS INT))
FROM dbo.MyTable

需要转换成数字

或其他解决方案 -

SELECT COUNT(*)
FROM dbo.MyTable
WHERE bitColumn = 1

【讨论】:

我的查询实际上比我的问题中的示例要复杂得多。 bitColumn 来自一个连接表,我的结果被分组。我不想停止返回 bitColumn 为 False 的结果。但是解决方案 1 是完美的。如此简单!【参考方案2】:

可以通过CONVERT实现,

SELECT SUM(CONVERT(INT, bitColumn)) FROM MyTable

【讨论】:

【参考方案3】:

您可以将 0 视为空值并简单地计算剩余值:

SELECT count(nullif(bitColumn, 0))
FROM MyTable;

【讨论】:

【参考方案4】:

您可以使用 CAST 和 CONVERT 函数将数据类型转换为整数或数字数据类型。

试试这个代码块:

SELECT SUM(CAST(bitColumn AS INT)) as bitColumn
FROM MyTable

SELECT CONVERT(INT, bitColumn) 
FROM MyTable

【讨论】:

【参考方案5】:

有点神秘:

declare @Foo as Bit = 1;
-- @Foo is a Bit.
select SQL_Variant_Property( @Foo, 'BaseType' );
-- But adding zero results in an expression with data type Int.
select SQL_Variant_Property( @Foo + 0, 'BaseType' );
select Sum( @Foo + 0 );

declare @Samples as Table ( Foo Bit );
insert into @Samples ( Foo ) values ( 0 ), ( 1 ), ( 0 ), ( 0 ), ( 1 ), ( 1 ), ( 1 ), ( 1 );
select Sum( Foo + 0 ) from @Samples;

这当然不会提高可读性或可维护性,但它很紧凑。

【讨论】:

【参考方案6】:
SELECT SUM(bitColumn * 1) FROM dbo.MyTable

通过乘法将位转换为int,干净且简单

【讨论】:

这似乎是所有解决方案中最简单优雅的。【参考方案7】:

你可以使用SIGN函数:

CREATE TABLE tab_x(b BIT);
INSERT INTO tab_x(b) VALUES(1),(0),(0),(NULL),(0),(1);

SELECT SUM(SIGN(b))
FROM tab_x;
-- 2

DBFiddle Demo

【讨论】:

【参考方案8】:

我的个人偏好是CASE 声明。

SELECT SUM(CASE WHEN bitColumn = 1 THEN 1 ELSE 0 END) FROM MyTable;

或者,如果您真的热衷于代码压缩IIF

SELECT SUM(IIF(bitColumn = 1, 1, 0)) FROM MyTable;

【讨论】:

以上是关于如何将 SUM 用于位列?的主要内容,如果未能解决你的问题,请参考以下文章

如何仅使用在不使用动态SQL的情况下检查的复选框,将WHERE子句设置为在多个位列上进行过滤?

位列第五大生产要素,大数据该如何突破隐私安全魔咒?

如何组合2位列

MS SQL Server 位列导出为布尔值

与布尔值 false 进行比较时,如何防止 Linq2Sql 否定位列?

最牛逼的集群监控系统,它始终位列第一。。