虽然 James 建议的按位运算符会起作用,但它在关系数据库中的性能并不高,尤其是当您尝试扩展到数百万条记录时。原因是 where 子句中的函数是不可搜索的(它们阻止了索引查找)。
我要做的是创建一个包含所有可能的标志和条件组合的表,这将启用条件上的索引查找。
填充标志条件。我用了一个(tinyint)。如果您需要更多标志,您应该能够扩展这种方法:
CREATE TABLE FlagConditions (
Flag TINYINT
, Condition TINYINT
, CONSTRAINT Flag_Condition PRIMARY KEY CLUSTERED (Condition,Flag)
);
CREATE TABLE #Flags (
Flag TINYINT IDENTITY(0,1) PRIMARY KEY CLUSTERED
, DummyColumn BIT NULL);
GO
INSERT #Flags
( DummyColumn )
SELECT NULL;
GO 256
CREATE TABLE #Conditions(Condition TINYINT PRIMARY KEY CLUSTERED);
INSERT #Conditions ( Condition )
VALUES (1),(2),(4),(8),(16),(32),(64),(128);
INSERT FlagConditions ( Flag, Condition )
SELECT
Flag, Flag & Condition
FROM #Flags f
CROSS JOIN #Conditions c
WHERE Flag & Condition <> 0;
DROP TABLE #Flags;
DROP TABLE #Conditions;
现在,您可以在需要有效查找枚举按位条件的任何时候使用 FlagConditions 表:
DECLARE @UserFlags TABLE (Username varchar(10), Flag tinyint);
INSERT @UserFlags(Username, Flag)
VALUES ('User1',6),('User2',4),('User3',14);
DECLARE @Condition TINYINT = 2;
SELECT u.*
FROM @UserFlags u
INNER JOIN FlagConditions fc ON u.Flag = fc.Flag
WHERE fc.Condition = @Condition;
这将返回:
Username Flag
---------- ----
User1 6
User3 14
您的 DBA 会感谢您走这条面向设置的路线。