检查很多colums至少有一个真实的'

时间:2016-04-22 15:15:33

标签: sql sql-server

我有一个包含很多列的表(比如200),它们都是布尔值。我想知道其中哪一个至少有一个记录设置为true。我提出了以下查询,该工作正常:

SELECT  sum(Case When [column1] = 1 Then 1 Else 0 End) as column1,
sum(Case When [column2] = 1 Then 1 Else 0 End) as column2, sum(Case
When [column3] = 1 Then 1 Else 0 End) as column3, FROM [tablename];

它将返回“真实”的行数。对于一个专栏。但是,这比我需要的信息更多,因此可能需要更昂贵的查询。该查询将继续扫描所有记录的所有字段,即使这不是必需的。

5 个答案:

答案 0 :(得分:0)

如果你在一个表上使用boolean实际上有200列/字段,那么类似下面的内容应该可以工作。

SELECT CASE WHEN column1 + column2  + column3 + ... + column200 >= 1 THEN 'Something was true for this record' ELSE NULL END AS My_Big_Field_Test 
FROM  [TableName];

答案 1 :(得分:0)

如果您只想知道最后一个布尔字段的行,则需要测试每个行。

像这样(也许):

SELECT ROW.*
FROM TABLE ROW
WHERE ROW.COLUMN_1 = 1 
OR ROW.COLUMN_2 = 1 
OR ROW.COLUMN_3 = 1 
OR ... 
OR ROW.COLUMN_N = 1;

答案 2 :(得分:0)

我刚刚学到了一些可能有用的CHECKSUM(*)。请尝试以下代码:

DECLARE  @T TABLE (
b1 bit
,b2 bit
,b3 bit
);

DECLARE @T2 TABLE (
b1 bit
,b2 bit
,b3 bit
,b4 bit
,b5 bit
);

INSERT INTO @T VALUES (0,0,0),(1,1,1);
INSERT INTO @T2 VALUES (0,0,0,0,0),(1,1,1,1,1);

SELECT CHECKSUM(*) FROM @T;
SELECT CHECKSUM(*) FROM @T2;

您将从结果中看到,无论一行中有多少列,如果它们都是值为0的位列,则CHECKSUM(*)的结果始终为0.

这意味着您可以在查询中使用WHERE CHECKSUM(*)<>0来节省引擎排除所有值均为0的行的麻烦。可能会提高性能。

即使它没有,但要知道这是一件很好的事情。

编辑:

您可以对每列执行EXISTS()函数。我知道EXISTS()函数在找到存在的值时会停止扫描。如果行数多于列数,则可能性能更高。如果列数多于行数,那么在每列上使用SUM()的当前查询可能是您可以做的最快的事情。

答案 3 :(得分:0)

我不在我的机器前面,但您也可以尝试按位或操作符:

SELECT * FROM [table name] WHERE column1 | column2 | column3 = 1

亚瑟的OR回答是我提供的另一个建议。尝试一些不同的建议,看看查询计划。另请参阅磁盘读取和CPU使用情况。 (SET STATISTICS IO ON和SET STATISTICS TIME ON)。

参见任何方法给出欲望结果和最佳表现......然后告诉我们: - )

答案 4 :(得分:0)

您可以使用表格

的查询
SELECT 
    CASE WHEN EXISTS (SELECT * FROM [Table] WHERE [Column1] = 1) THEN 0 ELSE 1 END AS 'Column1',
    CASE WHEN EXISTS (SELECT * FROM [Table] WHERE [Column2] = 1) THEN 0 ELSE 1 END AS 'Column2',
    ...

这种效率关键取决于你的桌子有多稀疏。如果列中的每一行都有0值,那么搜索1值的任何查询都需要进行全表扫描,除非有索引。这个场景(数百万行和数百列)的一个非常好的选择是columnstore index。从SQL Server 2012开始支持这些;从SQL Server 2014开始,它们不会导致表只读(这是它们采用的主要障碍)。

使用列存储索引,每个子查询应该需要恒定的时间,因此查询作为一个整体(事实上,对于数百列,此查询变得如此之大,以至于您可能会遇到输入缓冲区和需要将其拆分为较小的查询)。如果没有索引,只要表不稀疏,此查询仍然有效 - 如果它“快速”运行到具有1值的行,它就会停止。