为了好玩,我将直接回答您的问题。在大数据上,这不会很好地执行,但很多位列也不会。
我认为让您的整体设计具有正确的数据库设计、没有一堆位列并且仍然表现良好的答案是从您的主表中创建一个一对多的表,其中记录的存在意味着该选项已启用. 然后可以很好地索引并执行良好。您还可以遵循我在下面使用的类似查找表构造,结合子表中多行的 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')
);