Это альтернатива, без 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;
Это немного хуже из-за повторения в коде, немного более читаемым и аналогичные по стоимости выполнения.
План выполнения этого выглядит немного лучше, чем решение @ Andomar. Может быть, кто-то, кто может лучше расшифровать планы исполнения, может взвесить. – Daniel
Когда я запустил это и решение @ Andomar в той же партии, это было 44% от партии. – Daniel
+1 Хотя этот бит поддерживает только 4 бита, он быстрее, потому что он выполняет «левое полусоединение» без «различной сортировки». Отредактировал мой запрос, чтобы сделать то же самое. Круто. :) – Andomar