Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 检查大量列中至少一个“正确”_Sql_Sql Server - Fatal编程技术网

Sql 检查大量列中至少一个“正确”

Sql 检查大量列中至少一个“正确”,sql,sql-server,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

我有一个有很多列的表,比如说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];

它将返回列的“true”行数。然而,这是比我需要更多的信息,因此可能需要更昂贵的查询。该查询将继续扫描所有字段以查找所有记录,即使这不是必需的。

如果一个表上有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];

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

可能是这样的:

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;

我刚刚学到了一些关于校验和的知识,可能会有用。请尝试以下代码:

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的位列,则校验和*的结果始终为0

这意味着您可以在查询中使用WHERE CHECKSUM*0来避免引擎对所有值均为0的行求和的麻烦。可能会提高性能

即使没有,这也是一件好事

编辑:


可以对每列执行EXISTS函数。我知道EXISTS函数在找到存在的值时停止扫描。如果行多于列,则性能可能会更好。如果列多于行,则当前使用每列求和的查询可能是最快的操作。

我不在机器前面,但您也可以尝试按位or运算符:

SELECT * FROM [table name] WHERE column1 | column2 | column3 = 1
亚瑟的回答是我会提供的另一个建议。尝试一些不同的建议并查看查询计划。还可以查看磁盘读取和CPU使用情况。打开统计信息IO并打开统计信息时间


查看给出期望结果和最佳性能的任何方法…然后让我们知道:-

您可以使用表单查询

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值的查询都需要进行完整的表扫描,除非有索引。对于这种场景,数百万行和数百列的一个非常好的选择是。从SQL Server 2012开始支持这些功能;从SQL Server 2014开始,它们不会导致表为只读,这是采用它们的主要障碍


有了columnstore索引,每个子查询都需要固定的时间,整个查询也需要固定的时间。事实上,由于有数百列,此查询变得非常大,您可能会遇到输入缓冲区问题,需要将其拆分为更小的查询。如果没有索引,只要表不是稀疏的,这个查询仍然可以有效-如果它很快运行到一个值为1的行,它就会停止。

行有列,反之亦然。如上所述,你的问题相当令人困惑。您是否有200行,并且您想知道是否至少有一行,其中至少有一列是1?或者你的每一行都有200列吗?我见过更疯狂的东西,你想知道,对于每一行,是否至少有一列是1?可以做一些类似于从tablename中选择*的事情,其中1在column1,column2,Column3中你可以尝试选择MAXcolumn1作为column1。。。来自[表名]。听起来您想知道是否有任何一行对每一列都是真的。如果是这种情况,那么如果该列中的任何一行为真,MAX将返回1。在一个包含200多列的表中,我有数百万行。我想知道至少有一行且列值为“true”的每一列。大于等于1>=1这是个好主意。更新。虽然根据对查询的解释和对问题的评论,这可能不符合OP的需要:/您必须将CASTcolumn1添加为INT,因为不允许对位字段进行算术运算。我假设这就是OP在谈到布尔值时的意思。即使所有列都为0时校验和总是为0,也不一定意味着任何列都不是0。你必须深入研究它的实现。严格测试所有2^200个可能的组合恐怕已经过时了。。。例如,一个简单的校验和对所有不是实际校验和的列执行XOR,但对我来说,它在每偶数个1上都是0,即使它在所有0上也是0。我不知道XOR在TSQL语法方面会是什么样子,但如果使用*作为校验和的唯一参数,则使用行中的所有列。我不打算测试200位列的每个组合,你是对的,但如果你能找到一种方法,当任何一列的值为1时,校验和*为零,我就不客气了。这意味着具有不同值的两行将具有相同的校验和,即w
我们将无法达到校验和的目的,而且,据我公认的有限理解,这是不可能的。T-SQL中的XOR是^。但我真的不在乎你是否愿意消化headgear——我不会把任何解决方案的正确性押在任何开发人员缺乏想象力上。校验和的冲突属性是出了名的糟糕;我真的很容易相信,即使有大量的输出位可用,也会有列组合无法正确分配输入位。把寻找一个例子的负担转移给我是可以的,但如果你不介意的话,我也不会检查所有的组合-你的理解是错误的。校验和输出一个整数。它只有32位可用。因此,如果行的可用信息超过32位,则必须有具有不同列内容的行具有相同的校验和,这仅仅是因为没有足够的不同校验和来区分它们。这适用于任何校验和,而不仅仅是由校验和实现的校验和。校验和永远不能用来判断行是否完全相同,只是它们绝对不同。创建表tA位不为空、B位不为空、C位不为空、D位不为空、E位不为空、F位不为空、G位不为空、H位不为空、I位不为空;插入TA、B、C、D、E、F、G、H、I值1、0、0、0、0、0、1;从t;中选择校验和*;。你能把它做成顶帽子吗?我一直想看到有人吃顶礼帽-它将返回至少有一个列值为true的所有行。我希望所有列名中至少有一行的列值为true。不,这不是我想知道的。我想知道至少有一行值为“true”的列的所有列名。感谢您提供的信息。遗憾的是,在这方面,这张桌子是“稀疏的”。几个月后,我们将迁移到具有列存储索引的内存中表。