如何将 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子句设置为在多个位列上进行过滤?