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

发布于 2024-08-25 01:35:42 字数 238 浏览 7 评论 0原文

我有一个包含大量列的查询。我想选择并非所有列都等于 0 的行。

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

这真的是最简洁的方法吗?

假设我需要将其更改为忽略所有列均为 1 或负值时..需要大量剪切和粘贴..

I have a query with loads of columns. I want to select rows where not all the columns are equal to 0.

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

Is this really the tidiest way to do it?

Supposing I then need to change it to ignore when all columns are 1, or negative.. Its a lot of cut and paste..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

行至春深 2024-09-01 01:35:42

45 个单独的列似乎具有类似的含义。因此,我鼓励您正确规范化该表。如果这样做,查询会更简单并且性能可能会更好。

It appears as though the 45 individual columns have a similar meaning. As such, I would encourage you to properly normalize this table. If you did, the query would be simpler and would likely perform better.

我乃一代侩神 2024-09-01 01:35:42

您可以参数化查询并将其放入存储过程或表值函数中。无论您选择什么值,您只需要编写固定次数的查询(每个操作类型一次)。

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)

You could parameterize the query and put it in a stored procedure or table-valued function. You'd only need to write the query a fixed number of times (once per operation type) regardless of the value(s) you choose.

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)
半寸时光 2024-09-01 01:35:42

您可以使用 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

You could use CHECKSUM. However, I don't know the internals of CHECKSUM so can't guarantee it would work over large datasets.

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
堇色安年 2024-09-01 01:35:42

(1) 条件中的连接词有误 - 您需要 OR 而不是 AND。

问题修改后,上述观察结果不再正确。

(2) 如果你有 45 列需要过滤,你将很难做得比你所写的更好。尽管很痛苦...

这一观察结果仍然正确。

(1) You have the wrong connective in the condition - you need OR and not AND.

With the question amended, the observation above is no longer correct.

(2) If you have 45 columns that you need to filter on, you are going to be hard pressed to do any better than what you have written. Pain though it be...

This observation remains true.

友欢 2024-09-01 01:35:42

您可以添加一个计算列来为您进行计算。从技术上讲,它并没有变得更整洁,只是现在当您在任何查询中使用它时,您只需检查计算列而不是重复计算。

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

You could add a computed column that does the calculation for you. It is not technically any tidier, except that now when you use it in any query you only have to check the computed column as opposed to repeating the calculation.

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)
    )
);

If your numbers are constrained in some way to be >= 0, you could do something slightly tidier, such as:

WHERE col1 + col2 + col3 = 0 -- or 45, if there are 45 such columns
                             -- and you are looking for each column = 1
不语却知心 2024-09-01 01:35:42

您可以创建规范化结构的视图并将其用作此查询的源:


选择所有其他字段,“Column1”,COL1 FROM tableName
联盟
选择所有其他字段,'Column2, COL2 FROM TableName
联盟...
选择所有其他字段,“Column45”,COL45 FROM tableName

you could create a view of a normalized structure and use that as your source for this query:


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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文