Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Побитовое ИЛИ при группировке  [new]
Prolog
Member

Откуда: Москва
Сообщений: 2793
Кому интересно.
Сегодня возникла такая задача: при группировке значение столбца агрегировать не арифметическим сложением, а логическим - побитовым ИЛИ. Додумался до следующего:
declare @t table(n int, m int)
insert @t values(1,1),(1,1),(1,2),(1,2),(1,4),
                (2,1),(2,4),(2,4),(2,4)
select
  n,
  arith_sum = sum(m),
  bit_sum   = sum(distinct m)
from
  @t
group by
  n


narith_sumbit_sum
1107
2135
9 ноя 12, 20:15    [13449196]     Ответить | Цитировать Сообщить модератору
 Re: Побитовое ИЛИ при группировке  [new]
invm
Member

Откуда: Москва
Сообщений: 9836
declare @t table(n int, m int)
insert @t values(1,1),(1,1),(1,2),(1,2),(1,4),
                (2,1),(2,4),(2,4),
                (2,5)
select
  n,
  arith_sum  = sum(m),
  bit_sum1   = sum(distinct m),
  bit_sum2   = sum(distinct m & 0x01) + sum(distinct m & 0x02) + sum(distinct m & 0x04)
from
  @t
group by
  n
 
9 ноя 12, 20:45    [13449284]     Ответить | Цитировать Сообщить модератору
 Re: Побитовое ИЛИ при группировке  [new]
Prolog
Member

Откуда: Москва
Сообщений: 2793
invm, да, это более общий случай. Можно сделать и так:
bit_sum2   = max(m&1) + max(m&2) + max(m&4)

Правда, немного громоздко для всех 32 битов.

Кстати, без группировки можно и через локальную переменную:

declare @s int = 0
select @s=@s|m from @t where n=2
select @s

Жаль, что в select нельзя одновременно применять и локальные переменные и возвращаемыем данные из столбцов (например, как в update).
10 ноя 12, 07:03    [13451006]     Ответить | Цитировать Сообщить модератору
 Re: Побитовое ИЛИ при группировке  [new]
invm
Member

Откуда: Москва
Сообщений: 9836
Prolog,

Совсем общий случай:
declare @t table(n int, m int);

insert @t values(1,1),(1,1),(1,2),(1,2),(1,4),
                (2,1),(2,4),(2,4),(2,5);
with b as
(
 select
  mask
 from
  (
   values
    (0x00000001), (0x00000002), (0x00000004), (0x00000008), (0x00000010), (0x00000020),
    (0x00000040), (0x00000080), (0x00000100), (0x00000200), (0x00000400), (0x00000800),
    (0x00001000), (0x00002000), (0x00004000), (0x00008000), (0x00010000), (0x00020000),
    (0x00040000), (0x00080000), (0x00100000), (0x00200000), (0x00400000), (0x00800000),
    (0x01000000), (0x02000000), (0x04000000), (0x08000000), (0x10000000), (0x20000000),
    (0x40000000), (0x80000000)
  ) t(mask)
)
select
  t.n,
  sum(distinct t.m & b.mask)
from
  @t t cross join
  b
group by
  t.n;
10 ноя 12, 09:55    [13451062]     Ответить | Цитировать Сообщить модератору
 Re: Побитовое ИЛИ при группировке  [new]
ChA
Member

Откуда: Москва
Сообщений: 11317
Prolog
такая задача: при группировке значение столбца агрегировать не арифметическим сложением, а логическим - побитовым ИЛИ
1579923
2716283
10 ноя 12, 11:43    [13451178]     Ответить | Цитировать Сообщить модератору
 Re: Побитовое ИЛИ при группировке  [new]
Стало интересно
Guest
Стало интересно, а в каких реальных задача это нужно? Никогда с таким не сталкивался.
10 ноя 12, 12:08    [13451204]     Ответить | Цитировать Сообщить модератору
 Re: Побитовое ИЛИ при группировке  [new]
Prolog
Member

Откуда: Москва
Сообщений: 2793
Стало интересно
Стало интересно, а в каких реальных задача это нужно? Никогда с таким не сталкивался.

Я тоже до пятницы не сталкивался. Перекидываем данные из одной базы в другую. В 1й свойства объекта хранятся в дополнительной таблице по одной строке на свойство, во 2й в виде битов в столбце с типом int.

invm, для "cовсем общего случая" план исполнения по-хуже будет.
11 ноя 12, 08:26    [13454406]     Ответить | Цитировать Сообщить модератору
 Re: Побитовое ИЛИ при группировке  [new]
aleks2
Guest
declare @t table (n int, m int);
insert @t 
values (1, 1)
     , (1, 12345568)
     , (2, 56)
     , (2, 56)
;

with
nums as (select *, row_number() over(partition by n order by m asc) num, row_number() over(partition by n order by m desc) num2 from @t)
,
bitwisesum as 
( select m, n, num, num2 from nums where num = 1
  union all
  select bi.m|nu.m, bi.n, nu.num, nu.num2 from bitwisesum bi inner join nums nu on bi.num+1 = nu.num and bi.n = nu.n
)
  
  
select * from bitwisesum where num2 = 1
11 ноя 12, 15:59    [13454872]     Ответить | Цитировать Сообщить модератору
 Re: Побитовое ИЛИ при группировке  [new]
Добрый Э - Эх
Guest
2 aleks2,

"Фигня это фсе. На больших размерах данных тупо просрет временным таблицамaleks2 [/quot]
11 ноя 12, 16:42    [13454929]     Ответить | Цитировать Сообщить модератору
 Re: Побитовое ИЛИ при группировке  [new]
aleks2
Guest
Добрый Э - Эх
2 aleks2,

"Фигня это фсе. На больших размерах данных тупо просрет временным таблицамaleks2
[/quot]
До временных таблиц тредстатер ишо не дорос.
11 ноя 12, 19:37    [13455303]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить