我有一个包含大量列的查询。我想选择并非所有列都等于 0 的行。
select * from table
where
not
( column1 = 0 and
column2 = 0 and
column3 = 0 and
...
column45 = 0)
这真的是最整洁的方法吗?
假设我需要将其更改为在所有列为 1 或负数时忽略它。它需要大量的剪切和粘贴。
我有一个包含大量列的查询。我想选择并非所有列都等于 0 的行。
select * from table
where
not
( column1 = 0 and
column2 = 0 and
column3 = 0 and
...
column45 = 0)
这真的是最整洁的方法吗?
假设我需要将其更改为在所有列为 1 或负数时忽略它。它需要大量的剪切和粘贴。
看起来这 45 个单独的列具有相似的含义。因此,我鼓励您正确规范化此表。如果你这样做了,查询会更简单,并且可能会执行得更好。
您可以参数化查询并将其放入存储过程或表值函数中。无论您选择什么值,您只需要编写固定次数的查询(每种操作类型一次)。
create function dbo.fn_notequal_columns
(
@value int
)
returns table
as
(
select * from [table]
where column1 <> @value and column2 <> @value ...
)
select * from dbo.fn_notequal_columns(0)
您可以添加一个计算列来为您进行计算。从技术上讲,它并不整洁,只是现在当您在任何查询中使用它时,您只需检查计算列而不是重复计算。
CREATE TABLE dbo.foo
(
col1 INT,
col2 INT,
col3 INT,
all_0 AS
(
CONVERT(BIT, CASE
WHEN col1 = 0 AND col2 = 0 AND col3 = 0
THEN 1 ELSE 0
END)
)
);
如果您的数字以某种方式被限制为 >= 0,您可以做一些稍微整洁的事情,例如:
WHERE col1 + col2 + col3 = 0 -- or 45, if there are 45 such columns
-- and you are looking for each column = 1
(1) 您在条件中使用了错误的连接词 - 您需要 OR 而不是 AND。
修改问题后,上述观察不再正确。
(2) 如果您有 45 列需要过滤,那么您将很难做得比您所写的更好。虽然很痛...
这个观察仍然正确。
您可以使用校验和。但是,我不知道 CHECKSUM 的内部结构,所以不能保证它适用于大型数据集。
CREATE TABLE dbo.FooBar (
keyCol int NOT NULL IDENTITY (1, 1),
col1 int NOT NULL,
col2 int NOT NULL,
col3 int NOT NULL
)
INSERT FooBar (col1, col2, col3)
SELECT -45, 0, 45
UNION ALL
SELECT 0, 23, 0
UNION ALL
SELECT 0, 0, 0
UNION ALL
SELECT 1, 0, 0
SELECT
CHECKSUM(col1, col2, col3)
FROM
dbo.FooBar
SELECT
*
FROM
dbo.FooBar
WHERE
CHECKSUM(col1, col2, col3) = 0
您可以创建规范化结构的视图并将其用作此查询的源:
SELECT all other fields, 'Column1', COL1 FROM tableName
UNION
SELECT all other fields, 'Column2, COL2 FROM TableName
UNION ...
SELECT all other fields, 'Column45', COL45 FROM tableName