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

Откуда: Київ
Сообщений: 10428
Есть таблица с полем binary, содержащим по сути битовые флажки.
Нужно делать выборки из таблицы с проверкой значений множества флажков.

Как сделать выборку по флажкам в общем случае?
Сделать функцию, которой на вход будут подаваться список позиций битов и чтобы ее можно было использовать для выборки в общем случае?


DECLARE @nByteNum      integer
DECLARE @nBitNumInByte integer
DECLARE @nMask         integer
DECLARE @nBigBitNum    integer 
declare @t table(id int not null identity, id1 int, banner binary(128))

insert into @t(id1, banner)
select 1, 0x0
union all
select 1, 0x000100FF
union all
select 1, 0x010200FF
union all
select 10, 0x010208
union all
select 10, 0x000100
union all
select 10, 0x040000

select * from @t

SET @nBigBitNum= 24
SET @nByteNum= @nBigBitNum/8
SET @nBitNumInByte= @nBigBitNum % 8      -- 0,1...6,7
SET @nMask = POWER(2, @nBitNumInByte ) -- 128,64,... 2,1
SET @nByteNum= @nByteNum +1

select * from @t where SUBSTRING(banner, @nByteNum,1)&@nMask=@nMask
13 июн 14, 11:53    [16160803]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать выборку?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
да, можно считать, что списоr флажков (номеров битов) делается выборкой из другой таблицы

declare @flags table (int id, int pos)
13 июн 14, 11:55    [16160808]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать выборку?  [new]
Crimean
Member

Откуда:
Сообщений: 13147
не смущает, что сканы будут? а альтернативы алгоритму я не особо вижу - действительно, из binary брать нужный байт и его маскировать - вполне себе вариант
13 июн 14, 12:01    [16160817]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать выборку?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
Crimean
не смущает, что сканы будут? а альтернативы алгоритму я не особо вижу - действительно, из binary брать нужный байт и его маскировать - вполне себе вариант


да сканы то ладно, потестирую...

Мне бы найти как делать выборки c проверкой N позиций в одном поле, выше я привел пример с проверкой одного битаЮ а надо бы универсальный подход.
Т. е образно говоря как-т так

select * from @t where dbo.checkbits(banner)>0

А в этой функции проверка всех позиций, которые которые выбиратся из некоего вью v_pos.

Как красиво сделать?
13 июн 14, 12:39    [16160906]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать выборку?  [new]
Crimean
Member

Откуда:
Сообщений: 13147
вброшу. а если "вывернуть" задачку? то есть от каждого "banner" "сразу" сгенерировать коллекцию установленных битов? в результате дальше все сведется к всем знакомой работе с множествами. как-то так, к примеру:

declare @a binary( 10 ) -- 10 * 8 = 80 bits

--          1 2 3 4 5 6 7 8 9 0
set @a = 0x81000000000000000101

select pos
from
(
	select
		no as pos ,
		1 + (no-1) / 8 as byte ,
--		1 + (no-1) % 8 as bit ,
		cast( power( 2 , 7 - (no-1) % 8 ) as binary(1)) as mask
	from	dbo.fn_GetAllNumbers( 1 , 80 )
)	as	a
where	cast( substring( @a, byte, 1 ) as int ) & a.mask <> 0
order by 1


fn_GetAllNumbers - понятно что делает - дает номера от и до указанных. в этом примере у меня 10 - байтовый массив и я считаю биты "слева направо". вполне логично что выборка выдает у меня значения ( 1, 8, 72, 80 ). собственно, вместо функции тут вполне логично запилить постоянную табличку, где будут сразу храниться позиции, байты и маски, чтобы их не считать. ну и табличную. функцию дальше, параметром которой будет или бинарь или ИД таблички с бинарем - уже не очень суть важно
13 июн 14, 13:13    [16160994]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать выборку?  [new]
Crimean
Member

Откуда:
Сообщений: 13147
Winnipuh
да, можно считать, что списоr флажков (номеров битов) делается выборкой из другой таблицы

declare @flags table (int id, int pos)


развивая мысль - для @flags логично unique( id , pos ), соответственно можно писать выборку как-то, скажем, так:

select t.*
from @t as t
where exists( select 1 from udf( t.banner ) as udf join @flags as f on f.id = t.id and f.pos = udf.pod )
13 июн 14, 13:18    [16161004]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать выборку?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
вброс "защитан", ушел пробовать этот вариант
13 июн 14, 16:17    [16161436]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать выборку?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Так уже же была эта задача сделана для вас: 16126008
13 июн 14, 21:35    [16162152]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать выборку?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
Mnior
Так уже же была эта задача сделана для вас: 16126008


спасибо, там дан вариант,но на больших таблицах производительность не очень хорошая.
Вот и пытаюсь искать пути.
14 июн 14, 11:07    [16162860]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать выборку?  [new]
aleks2
Guest
Winnipuh
Mnior
Так уже же была эта задача сделана для вас: 16126008


спасибо, там дан вариант,но на больших таблицах производительность не очень хорошая.
Вот и пытаюсь искать пути.


Ну как маленький, прямо.
Гдеж ты видал хорошую производительность при сканировании больших таблиц?
14 июн 14, 11:23    [16162881]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать выборку?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
Можно так подойти
как делать быстрое сравнение двух binary, один из которых - шаблон для сравнения, а второй - колонка в таблице при выборке
Правило такое: эти два значения равны, поскольку у них совпадает как миниум одна позиция, и этого достаточно.

declare @template binary(128) = 0x0401020108
declare @value      binary(128) = 0x0801010204
14 июн 14, 11:53    [16162906]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать выборку?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
aleks2
Winnipuh
пропущено...


спасибо, там дан вариант,но на больших таблицах производительность не очень хорошая.
Вот и пытаюсь искать пути.


Ну как маленький, прямо.
Гдеж ты видал хорошую производительность при сканировании больших таблиц?


вот именно... но как-то же можно решить ;-)
14 июн 14, 11:54    [16162909]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать выборку?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
aleks2
Ну как маленький, прямо.
Нечего пенять набитого опилками. Он хочет чтобы поиск работал быстрее чем тупой скан таблицы, как по вошебству. Гуманитарии, сэр.
Winnipuh
на больших таблицах производительность не очень хорошая.
Или, как обычно, сделал не так как предложено, поэтому и не фунчиклирует.
Сколько работает полный скан, а сколько "поиск"?
14 июн 14, 20:16    [16163688]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить