2014-04-15 2 views
2

저는 꽤 오래 동안 tsql 작업을 해왔지만 WHERE 절에서 binary oring 또는 oring을 본 적이 없습니다. 이제는 비트 마스크를 적용하면 도움이 될 새로운 애플리케이션을 개발 중입니다. 제품 등급이 16 점이라고 가정 해 보겠습니다. 각 등급은 비트 [] 열의 비트 위치로 나타냅니다. 따라서 A109 학년은 0000000000000001, B704 학년은 0000001000000000, V64 학년은 0100000000000000 등입니다. 모든 학년은 배열 열에 1을 하나만 가질 수 있습니다. 이제 제조 과정에서 3 가지 등급을 서로 바꿀 수 있다고 가정 해 봅시다. 그래서이 검색을위한 비트 마스크는 0100001000000001이 될 것입니다. WHERE 절을 작성하여 3 가지 등급의 항목을 모두 나열하려면 어떻게해야합니까?비트 배열을 tsql의 비트 마스크와 비교합니다.

+0

여기를 살펴보십시오. http://technet.microsoft.com/en-us/library/ms176122.aspx – cha

+0

정확하게 수행하려고하는 것은 무엇입니까? 가지고있는 데이터의 예를 들어 줄 수 있습니까? 일치하는 행 또는 2 행과 일치하지 않는 행 또는 2 행? 의미, 당신은 3 항목을 포함하는 bitmasked 값을 전달하는 경우 일치가) 적어도 그 3, b)는 그 3, 또는 그 3 중 하나만 c가 있어야합니까? 이 (따라서 받아 들여진 답)이 완전히 잘못된 접근 일 가능성이 높습니다. –

답변

0

좀 더 많은 연구와 최상의 솔루션이 인이

WHERE mask1 & mask2 <> 0 

같은 비트 AND 연산자와 마스크를 비교하는 것입니다했다 쉽고 간단하고 응집력있는

1

처음으로 나에게도. 흥미 롭 군.

declare @A109 int = 1; 
declare @B704 int = 512; 
declare @V64 int = 16384; 
declare @Xx int = 32; 

declare @mask int = 16897; [email protected][email protected][email protected] 

create table #MyData (
    name char(2), 
    value int); 

insert #MyData 
values ('a', @A109), ('b1', @B704), ('b2',@B704), ('c', @Xx); 

select 
    name, 
    value 
from #MyData 
where (value & @mask) in (@A109, @B704, @V64); 

drop table #MyData; 

이진 데이터에서 비트 연산을 수행 할 수없는 것 같습니다. "In a bitwise operation, only one expression can be of either binary or varbinary data type".

+0

이것은 꽤 좋지만 응용 프로그램에서이 검색을 사용해야하므로 솔루션 목록을 제공 할 수 없기 때문에 마스크 형식으로 하나의 매개 변수를 제공해야합니다. – ArtK

1

이 경우 WHERE 절은 이진수의 10 진수 (기본 10)를 처리 할 때 매우 간단합니다 ... 귀여운 경우는 JOIN입니다. 명확하게하기 위해이 접근법은 bit [] 열 또는 BINARY 유형 (단지 INT)을 사용하지 않습니다.

희망이 있으면 도움이 될 것입니다.

DECLARE @G1 INT = 1, -- 0000001 
     @G2 INT = 2, -- 0000010 
     @G3 INT = 4, -- 0000100 
     @G4 INT = 8, -- 0001000 
     @G5 INT = 16, -- 0010000 
     @G6 INT = 32, -- 0100000 
     @G7 INT = 64 -- 1000000 

;WITH Grading (Grade, BinScore) AS 
(
    SELECT 'G1', 1 UNION ALL 
    SELECT 'G2', 2 UNION ALL 
    SELECT 'G3', 4 UNION ALL 
    SELECT 'G4', 8 UNION ALL 
    SELECT 'G5', 16 UNION ALL 
    SELECT 'G6', 32 UNION ALL 
    SELECT 'G7', 64 

) 
,Product (ProductName, BinGrading) AS 
(
    SELECT 'Foobar',  73 UNION ALL 
    SELECT 'Franglesnap', 3 UNION ALL 
    SELECT 'Mebble',  32 
) 
SELECT * 
FROM Product 
WHERE BinGrading = (@G1 + @G4 + @G7) 
-- Alternatively... 
--SELECT * 
--FROM Product P 
--JOIN Grading G ON P.Bingrading & G.BinScore > 0 
+0

답변에 가까워지면 가까이에있는 것 같아서 더 많은 안내가 필요할 수 있습니다. 하나의 매개 변수 만 전달되는 sp에서 필터링을 수행하고 싶습니다. 이 param은 int 또는 equivalent 비트 배열 중 하나입니다. 개별적으로 비트 마스크를 "해결"하기 위해 UNION 또는 JOIN을 사용해야합니까? – ArtK

+0

편집 방을 더 얻으려는 또 다른 답변을 게시했지만 @MarkD에 있습니다. –

2

UI에서 사용자는 자신이 좋아하는만큼의 성적을 선택할 수 있습니다. 무대 뒤에서는 각 등급이 int로 매핑됩니다 - MarkD의 솔루션에있는 Grading 표. 응용 프로그램에서 이러한 int 합계. 합계를 SP에 전달하십시오.

SQL :

create procedure dbo.GetMaskedList @mask int = 0; 
... 
    WHERE BinGrading = @mask; 

UI :

int mask = 0; 
foreach(item in selectList) 
{ 
    mask += item.BinScore; 
} 

exec GetMaskedList @mask = mask; 
관련 문제