多数の列を含むクエリがあります。すべての列が 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 の個々の列が同様の意味を持っているように見えます。そのため、この表を適切に正規化することをお勧めします。そうした場合、クエリはより単純になり、パフォーマンスが向上する可能性があります。
クエリをパラメーター化して、ストアド プロシージャまたはテーブル値関数に入れることができます。選択した値に関係なく、一定回数 (操作の種類ごとに 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)
計算を行う計算列を追加できます。技術的にはそれほど整然としたものではありませんが、クエリで使用する場合は、計算を繰り返すのではなく、計算列をチェックするだけで済みます。
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) 条件の接続詞が間違っています - AND ではなく OR が必要です。
質問が修正されたため、上記の観察はもはや正しくありません。
(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