过滤掉所有列=值的行的最简洁方法

时间:2010-03-08 17:00:27

标签: sql sql-server tidy

我有一堆列的查询。我想选择并非所有列都等于0的行。

select * from table
where 
not
( column1 = 0 and
  column2 = 0 and
  column3 = 0 and
  ...
  column45 = 0)

这真的是最干净的方式吗?

假设我需要将其更改为忽略所有列为1或负数时..它会进行大量剪切和粘贴..

6 个答案:

答案 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