我想获得下一个表的按位AND比较结果
gr 值
1 300
1 340
1 150
2 520
2 460
在这个例子中,我希望看到300,340和150(组1)之间以及520和460(组2)之间的比较。 问题是每个组中的元素数量可以是任意数量。
答案 0 :(得分:0)
你可以这样做你想做的事情:
select gr,
(min(value & 1) + min(value & 2) + min(value & 4) + min(value & 8) + min(value & 16) +
min(value & 32) + min(value & 64) + min(value & 128) + min(value & 256) & min(value & 512)
) as bit_and
from table t
group by gr;
您可能需要将汇总扩展为更高的位值。
答案 1 :(得分:0)
这里的例子(感谢Vyacheslav Davydenko):
-- example for aggregate bitwise operations
SET NOCOUNT ON
declare @t table (gr int, mask tinyint)
INSERT INTO @t(gr, mask) VALUES
(1, 1) -- 00000001
,(1, 3) -- 00000011
,(1, 5) -- 00000101
,(2, 9) -- 00001001
,(2, 8) -- 00001000
select 'source',* from @t
declare @maskSize tinyint = 8*(select top 1 DataLength(mask) from @t) -- bits count
-- bitwise AND
;with Bits as
(
select BitMask=cast(1 as bigint)
union all
select 2 * BitMask from Bits where BitMask < POWER(cast(2 as bigint), @maskSize)
)
, ResultBit AS
(
select gr, res=sum(BitMask)
from (
select gr, BitMask, cnt=count(BitMask), sm=sum(res)
from (
select
t.gr
,b.BitMask
,res=iif(t.mask & b.BitMask=0, 0, 1)
from @t t
cross join Bits b
)z
group by gr, BitMask
having count(BitMask)=sum(res)
)z
group by gr
)
select example='AND',* from ResultBit
order by gr
-- bitwise OR
;with Bits as
(
select BitMask=cast(1 as bigint)
union all
select 2 * BitMask from Bits where BitMask < POWER(cast(2 as bigint), @maskSize)
)
, ResultBit AS
(
select
gr
,res=SUM(DISTINCT iif(t.mask & b.BitMask=0, 0, b.BitMask)) --
from @t t
cross join Bits b
group by gr
)
select example='OR',* from ResultBit
结果你得到:
;gr;mask
source;1;1
source;1;3
source;1;5
source;2;9
source;2;8
example;gr;res
AND;1;1
AND;2;8
example;gr;res
OR;1;7
OR;2;9