比较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