楽しみのために、私はあなたの質問に直接答えます。大規模なデータでは、これはうまく機能しませんが、多くのビット列もうまく機能しません。
全体的な設計が正しいデータベース設計を持ち、多数のビット列を持たず、それでもうまく機能するための答えは、メインテーブルから 1 対多のテーブルを作成することだと思います。ここで、レコードが存在するということは、オプションが有効になっていることを意味します。 . これは適切にインデックス化され、適切に実行されます。以下で使用している同様のルックアップ テーブルの構成に従って、子テーブルの複数の行にわたって SUM() と組み合わせて、複数のレコードを C# 列挙型に変換することもできます。テーブルの更新は、巧妙に作成された MERGE ステートメントでも実行できます。ただし、そのソリューションのコードは少し引き出されており、元の質問の範囲外です。
CREATE TABLE dbo.Data
(
ID int IDENTITY(1,1) NOT NULL PRIMARY KEY,
Name varchar(50) NOT NULL,
Flags int NOT NULL DEFAULT(0)
);
CREATE TABLE dbo.Flag
(
Value int NOT NULL PRIMARY KEY,
Name varchar(50) NOT NULL
);
INSERT INTO dbo.Flag
SELECT 1, 'Option A'
UNION ALL
SELECT 2, 'Option B'
UNION ALL
SELECT 4, 'Option C';
INSERT INTO dbo.Data (Name, Flags)
SELECT 'George', 0
UNION ALL
SELECT 'Bob', 1
UNION ALL
SELECT 'Bill', 3;
-- for C#
SELECT
d.ID,
d.Name,
d.Flags
FROM
dbo.Data d;
-- for other callers vertical
SELECT
d.ID,
d.Name,
d.Flags,
f.Name AS Flag,
f.Value
FROM
dbo.Data d
LEFT JOIN dbo.Flag f ON
d.Flags & f.Value = f.Value;
-- for other callers horizontal
SELECT
p.Name,
p.[Option A],
p.[Option B],
p.[Option C]
FROM
(
SELECT
d.Name,
f.Name AS Flag,
f.Value
FROM
dbo.Data d
LEFT JOIN dbo.Flag f ON
d.Flags & f.Value = f.Value
) d
PIVOT
(
COUNT(d.Value)
FOR d.Flag IN ([Option A], [Option B], [Option C])
) p;
SELECT
d.ID,
d.Name,
d.Flags
FROM
dbo.Data d
WHERE
EXISTS
(
SELECT *
FROM
dbo.Flag f
WHERE
d.Flags & f.Value = f.Value AND
f.Name IN ('Option A', 'Option B')
);