Это альтернатива, без WITH (ура !!!):
select sum(distinct isnull(n & BitMask, 0)) as resultvalue
from
(
SELECT 1 AS n
UNION ALL
SELECT 2
UNION ALL
SELECT 4
UNION ALL
SELECT 3
) t
INNER JOIN (SELECT 0 BitMask union all SELECT 1 union all SELECT 2 union all SELECT 4 union all SELECT 8 union all SELECT 16 union all SELECT 32 union all SELECT 64 union all SELECT 128 union all SELECT 256 union all SELECT 512 union all SELECT 1024 union all SELECT 2048 union all SELECT 4096 union all SELECT 8192 union all SELECT 16384 union all SELECT 32768 union all SELECT 65536) Bits -- = SELECT POWER(2, 16)
ON n & BitMask = BitMask;
Также рассмотрим группу по примеру:
-- Setup temp table to produce an example --
create table #BitValues
(
id int identity(1,1)
,value int
,groupby varchar(10)
)
insert into #BitValues
SELECT 1 AS value, 'apples'
UNION ALL
SELECT 2, 'apples'
UNION ALL
SELECT 4, 'apples'
UNION ALL
SELECT 3, 'apples'
-- Bit operation: --
select groupby, sum(distinct isnull(value & BitMask, 0)) as tempvalue
from #BitValues
INNER JOIN (SELECT 0 BitMask union all SELECT 1 union all SELECT 2 union all SELECT 4 union all SELECT 8 union all SELECT 16 union all SELECT 32 union all SELECT 64 union all SELECT 128 union all SELECT 256 union all SELECT 512 union all SELECT 1024 union all SELECT 2048 union all SELECT 4096 union all SELECT 8192 union all SELECT 16384 union all SELECT 32768 union all SELECT 65536) Bits -- = SELECT POWER(2, 16)
ON value & BitMask = BitMask
group by groupby
Первый пример должен быть медленнеечем с.Однако, когда вы используете GroupBy с некоторыми другими данными, запросы в значительной степени одинаковы по стоимости.
Другой способ сделать это -
select
groupby
,max(case when n & 1 = 1 then 1 else 0 end)
+
max(case when n & 2 = 2 then 2 else 0 end)
+
max(case when n & 4 = 4 then 4 else 0 end)
+
max(case when n & 8 = 8 then 8 else 0 end)
+
max(case when n & 16 = 16 then 16 else 0 end)
+
max(case when n & 32 = 32 then 32 else 0 end)
+
max(case when n & 64 = 64 then 64 else 0 end)
+
max(case when n & 128 = 128 then 128 else 0 end)
+
max(case when n & 256 = 256 then 256 else 0 end)
+
max(case when n & 512 = 512 then 512 else 0 end)
+
max(case when n & 1024 = 1024 then 1024 else 0 end)
as NewDNC
from #BitValues
group by groupby;
Это немного хуже из-за повторения в коде, немного более читаемый и похожий по стоимости исполнения.