我有一堆列的查询。我想选择并非所有列都等于0的行。
select * from table
where
not
( column1 = 0 and
column2 = 0 and
column3 = 0 and
...
column45 = 0)
这真的是最干净的方式吗?
假设我需要将其更改为忽略所有列为1或负数时..它会进行大量剪切和粘贴..
答案 0 :(得分:3)
似乎45个单独的列具有相似的含义。因此,我鼓励您正确地规范化此表。如果你这样做,查询会更简单,并且可能会表现更好。
答案 1 :(得分:1)
(1)你在条件中有错误的连接词 - 你需要OR而不是AND。
随着问题的修改,上面的观察不再正确。
(2)如果您需要过滤45列,那么您将很难做出比您所写的更好的列。痛苦虽然是......
这种观察仍然存在。
答案 2 :(得分:1)
您可以参数化查询并将其放在存储过程或表值函数中。无论您选择哪个值,您只需要将查询写入固定次数(每个操作类型一次)。
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)
答案 3 :(得分:1)
您可以使用CHECKSUM。但是,我不知道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
答案 4 :(得分: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)
)
);
您还可以做一些稍微整洁的事情,例如:
WHERE col1 + col2 + col3 = 0 -- or 45, if there are 45 such columns
-- and you are looking for each column = 1
答案 5 :(得分: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