雖然詹姆斯提出的位運算符將工作,它不會是很在關係數據庫中執行,尤其是當您嘗試擴展到數百萬條記錄時。原因是where子句中的函數不是可靠的(它們阻止索引查找)。
我會做的是創建一個表,其中包含標誌和條件的所有可能的組合,這將啓用條件上的索引查找。
填充FlagConditions。我用了一個(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會感謝您參加此集合導向的路線。
這將是更「類似SQL的」存儲此信息在多對多表中。所以你應該把行(1,1),(1,2),(2,2),(3,1),(3,2),(3,3)'存儲在一個單獨的表中。它會使更自然的查詢,並提供索引機會。 –