比较SQL中的两个位掩码,看是否有任何位匹配

有没有办法在Transact-SQL中比较两个位掩码来查看是否有位匹配? 我有一个用户所有angular色的位掩码的用户表,我想select提供的位掩码中的任何angular色的所有用户。 因此,使用下面的数据,angular色位掩码6(devise师+程序员)应该select戴夫,查理和苏珊,但不是尼克。

 用户表
 ----------
 ID用户名angular色
 1戴夫6
 2查理2
 3苏珊4
 4尼克1

angular色表
 -----------
 IDangular色
 1pipe理员
 2程序员
 4devise师 

有任何想法吗? 谢谢。

您的问题的答案是使用按位&像这样:

 SELECT * FROM UserTable WHERE Roles & 6 != 0 

6可以交换你的位域的任何组合,你想检查任何用户有一个或多个这些位。 当试图validation这一点时,我通常会发现用二进制编写这个代码是很有帮助的。 你的用户表如下所示:

  1 2 4 ------------------ Dave 0 1 1 Charlie 0 1 0 Susan 0 0 1 Nick 1 0 0 

你的testing(6)是这样的

  1 2 4 ------------------ Test 0 1 1 

如果我们经历每个人的bit And而反对testing,我们得到这些:

  1 2 4 ------------------ Dave 0 1 1 Test 0 1 1 Result 0 1 1 (6) Charlie 0 1 0 Test 0 1 1 Result 0 1 0 (2) Susan 0 0 1 Test 0 1 1 Result 0 0 1 (4) Nick 1 0 0 Test 0 1 1 Result 0 0 0 (0) 

上面应该certificate结果不为零的logging有一个或多个请求的标志。

编辑:这是testing用例,如果你想检查这个

 with test (id, username, roles) AS ( SELECT 1,'Dave',6 UNION SELECT 2,'Charlie',2 UNION SELECT 3,'Susan',4 UNION SELECT 4,'Nick',1 ) select * from test where (roles & 6) != 0 // returns dave, charlie & susan 

要么

 select * from test where (roles & 2) != 0 // returns Dave & Charlie 

要么

 select * from test where (roles & 7) != 0 // returns dave, charlie, susan & nick 

使用Transact-SQL 按位与运算符 “&”并将结果与​​零进行比较。 更好的是,不是将angular色编码为整数列的位,而是使用布尔列,每个angular色一列。 那么你的查询将只是devise师和程序员友好。 如果您希望angular色在应用程序的整个生命周期中发生很大的变化,那么可以使用多对多的表来映射用户和angular色之间的关联。 两个替代scheme比依靠按位与运算符的存在更具可移植性。

 SELECT * FROM UserTable WHERE Roles & 6 > 0 

SELECT * FROM table WHERE mask1&mask2> 0

例:

 DECLARE @Mask int SET @Mask = 6 DECLARE @Users TABLE ( ID int, Username varchar(50), Roles int ) INSERT INTO @Users (ID, Username, Roles) SELECT 1, 'Dave', 6 UNION SELECT 2, 'Charlie', 2 UNION SELECT 3, 'Susan', 4 UNION SELECT 4, 'Nick', 1 SELECT * FROM @Users WHERE Roles & @Mask > 0 

要find所有的程序员使用:

 SELECT * FROM UserTable WHERE Roles & 2 = 2