Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / WHERE по битовой маске / 25 сообщений из 43, страница 1 из 2
30.07.2013, 16:00:09
    #38348978
aleksey_sql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
Народ, всем привет!
у меня следующий вопрос. Бьюсь уже продолжительное время, надеюсь на Вашу помощь.
Есть две следующие таблички, приведу код их формирования:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
CREATE TABLE IF NOT EXISTS `groups` (
  `group` varchar(10) DEFAULT 'NULL',
  `filter` varchar(1024) DEFAULT 'NULL'
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `subgroups` (
  `subgroup` varchar(10) DEFAULT 'NULL',
  `filter` varchar(1024) DEFAULT 'NULL'
) ENGINE=MyISAM DEFAULT CHARSET=utf8;



в этих таблицах поля group, subgroup - это текст (название групп и подгрупп), а filter - это некая последовательность 0b00101010100010000 и т.д.
Мне нужно получить все записи из таблицы subgroups, которые удовлетворяют значению битовой маски какой-то записи в таблице group. Как это сделать, помогите плиззз....

PS.: база писалась не мною, я лишь пытаюсь изменить клиентскую часть проги.
...
Рейтинг: 0 / 0
30.07.2013, 16:26:56
    #38349071
ScareCrow
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
where groups.filter = subgroups.filter ?
...
Рейтинг: 0 / 0
30.07.2013, 16:33:43
    #38349088
aleksey_sql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
ScareCrowwhere groups.filter = subgroups.filter ?
не. в groups поле filter принимает какое-то значение. например, возьмем 0b11100000000
а в subgroups мне нужно выбрать все подгруппы, которые удовлетворяют этой битовой маске.
гугл говорит что надо делать что то типа такого:
select * from subgroups where filter & '0b11100000000'
но так не получается. возвращается 0 строк...
...
Рейтинг: 0 / 0
30.07.2013, 16:46:07
    #38349125
SergeyPerm
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
aleksey_sqlScareCrowwhere groups.filter = subgroups.filter ?
не. в groups поле filter принимает какое-то значение. например, возьмем 0b11100000000
а в subgroups мне нужно выбрать все подгруппы, которые удовлетворяют этой битовой маске.
гугл говорит что надо делать что то типа такого:
select * from subgroups where filter & '0b11100000000'
но так не получается. возвращается 0 строк...

select * from subgroups where filter & b'011100000000' = b'011100000000'
?
...
Рейтинг: 0 / 0
30.07.2013, 16:46:13
    #38349126
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
Напрямую - никак.
Можно попробовать выцеплять нужные символы, затем уже в них проверять нужные биты.
http://dev.mysql.com/doc/refman/5.5/en/bit-functions.html MySQL uses BIGINT (64-bit) arithmetic for bit operations, so these operators have a maximum range of 64 bits.
При этом еще нужно с кодировками не налажать, ибо хранить бинарные данные в utf8 несколько, имхо, странно.

И, кстати, понятие "удовлетворяют этой битовой маске" нужно расшифровать. Или это точное равенство, или установленные биты, или снятые биты, или еще что-то...
...
Рейтинг: 0 / 0
30.07.2013, 20:06:37
    #38349381
aleksey_sql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
miksoftНапрямую - никак.
Можно попробовать выцеплять нужные символы, затем уже в них проверять нужные биты.
http://dev.mysql.com/doc/refman/5.5/en/bit-functions.html MySQL uses BIGINT (64-bit) arithmetic for bit operations, so these operators have a maximum range of 64 bits.
При этом еще нужно с кодировками не налажать, ибо хранить бинарные данные в utf8 несколько, имхо, странно.

И, кстати, понятие "удовлетворяют этой битовой маске" нужно расшифровать. Или это точное равенство, или установленные биты, или снятые биты, или еще что-то...

печально что напрямую никак. а я уж думал и в сторону substr при представлении бинарного поля как строку (varchar)
...
Рейтинг: 0 / 0
30.07.2013, 20:13:10
    #38349383
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
aleksey_sqlа я уж думал и в сторону substr при представлении бинарного поля как строку (varchar)Ну как-то так можно попробовать, но учтите, что substr работает с символами, а не байтами. А в utf8 символ имеет переменную длину в байтах.

Нельзя ли сменить структуру таблицы?
Что покажут следующие запросы:
Код: sql
1.
SELECT MAX(BIT_LENGTH(`filter`)) FROM `groups`

Код: sql
1.
SELECT MAX(BIT_LENGTH(`filter`)) FROM `subgroups`

?
...
Рейтинг: 0 / 0
30.07.2013, 21:21:36
    #38349429
netwind
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
Ну офигеть теперь. что значит напрямую нельзя ?
Для того чтобы найти такие записи, нужно просто написать запрос находящий эти записи!
Операции с битовыми масками в mysql обрабатываются точно так же как и в других языках программирования.
Есть OR, AND.


У vbulletin подобная структура для представления логических свойств разных сущностней и никто не помер.
...
Рейтинг: 0 / 0
30.07.2013, 21:23:32
    #38349433
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
netwindОперации с битовыми масками в mysql обрабатываются точно так же как и в других языках программирования.
Есть OR, AND.Только не для varchar(1024) с CHARSET=utf8.
...
Рейтинг: 0 / 0
30.07.2013, 21:51:25
    #38349459
netwind
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
а, понятно

ну сконвертировать на лету дело-то несложное :

select conv(replace('0b010101','0b',0),2,10) & conv('00100',2,10);

первая строка - то самое поле. вторая - маска для битового AND. в этом примере результат не равен 0 только когда третий бит установлен
...
Рейтинг: 0 / 0
30.07.2013, 21:53:32
    #38349462
netwind
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
aleksey_sql а filter - это некая последовательность 0b00101010100010000 и т.д.

вот это примером проиллюстрируйте типа select * from groups.
непонятно, там действительно двоичная запись ?
...
Рейтинг: 0 / 0
31.07.2013, 06:51:38
    #38349577
Arhat109
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
aleksey_sql,

1. VARCHAR(1024) UTF-8 - это конечно круто для битовых масок. Сразу: какова реальная максимальная длина битовой строки фильтра?

То есть, что показывает запрос вида SELECT MAX(CHAR_LENGTH(filter)-2) FROM `groups`; для этого поля?

Это ключевой вопрос по возможности "конвертировать" такую строку во что-то "удобо варимое".

2. Если длина меньше или равна 64 полезных бит, то как советовал netwind - конвертируете в длинное целое и работаете обычными побитовыми операциями. Можно сделать копии этих колонок в виде длинного целого, дабы не конвертить на лету в запросах.

3. А вот ежели - нет, но их не шибко много - можно попробовать разбить по 64 бита строковыми функциями и разогнать по нескольким полям.

4. А вот ежели там все 1024 бита... примите мои поздравления. Разгонять в 64 поля и клеить их потом в запросе... думаю обработка строковыми функциями будет живее даже. :)
...
Рейтинг: 0 / 0
31.07.2013, 06:53:53
    #38349579
Arhat109
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
Arhat109,

Кстати, вы писали, что "разработка не ваша, так было"... а "спросить" - не у кого (где аффтар?), посмотреть КАК оно работало раньше - никак (код снесли)?
...
Рейтинг: 0 / 0
31.07.2013, 09:40:32
    #38349640
deblogger
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
никакая это не битовая маска хосподи. Это код выбора каких-то опций. 1 - вкл, 0 - выкл, или наоборот, а что каждый вкл/выкл значит - знает только приложение.

Ну вот, поскольку это обычные строки их можно сравнить. Если же хочется вычитать или складывать и использовать результат для условия выборки, то наверно придется сперва конвертировать.

Код: sql
1.
select conv("0101", 2, 2) & conv("0100", 2, 2) as res



res
---
100
...
Рейтинг: 0 / 0
31.07.2013, 09:48:11
    #38349651
deblogger
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
aleksey_sql например, возьмем 0b11100000000
а в subgroups мне нужно выбрать все подгруппы, которые удовлетворяют этой битовой маске.


В вашем случае возьмем "11100000000" судя по варчарам.

Это значит вы получите 11100000000 для всех значений полей в которых записано последние три бита установлены в 1. Например 11100000000 & 11100000011 = 11100000000, 11100000000 & 11111111111 = 11100000000 и так далее. Или 11100000000 & 10100000000 != 11100000000.

Вы этого хотите?
...
Рейтинг: 0 / 0
31.07.2013, 10:12:33
    #38349680
Arhat109
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
deblogger,

да понятно, что "сейчас" - это просто строка, также понятно что это какое-то множество переключателей... и вполне возможно - битовое представление наличия того или иного параметра у группы, например "товаров". Если надо найти такие же строки фильтра в другой таблице - то тупо сравниваем оба текста промеж себя... и пофиг как и что в них закодировано. А вот если надо найти заданный набор переключателей в другой табличке - то их надо вычленять на лету... как? сильно зависит от предельной длины этих строк.

К сожалению, автор похоже или решил задачку или забил на неё... (а мы тут внезапно теоретизируем)
...
Рейтинг: 0 / 0
31.07.2013, 10:14:21
    #38349684
aleksey_sql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
debloggeraleksey_sql например, возьмем 0b11100000000
а в subgroups мне нужно выбрать все подгруппы, которые удовлетворяют этой битовой маске.


В вашем случае возьмем "11100000000" судя по варчарам.

Это значит вы получите 11100000000 для всех значений полей в которых записано последние три бита установлены в 1. Например 11100000000 & 11100000011 = 11100000000, 11100000000 & 11111111111 = 11100000000 и так далее. Или 11100000000 & 10100000000 != 11100000000.

Вы этого хотите?

Честно говоря, это база данных приложения, которое писал НЕ я.
Я лишь пытаюсь понять, что происходит в этой БД (какие связи), и каким макаром фильтровать по этому полю.
Моя задача - написать web-морду для этой базы. Всё складывалось нормально, пока не дошло до этого поля filter.
Приведу более полный пример:
Первая таблица:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
CREATE TABLE IF NOT EXISTS `series` (
  `abbrev` varchar(1024) DEFAULT 'NULL' COMMENT 'char(*)',
  `catcode` varchar(1024) DEFAULT 'NULL' COMMENT 'char(*)',
  `catname` varchar(1024) DEFAULT 'NULL' COMMENT 'char(*)',
  `catkeys` varchar(1024) DEFAULT 'NULL' COMMENT 'char(*)',
  `catser` varchar(1024) DEFAULT 'NULL' COMMENT 'char(*)',
  `e_codes` varchar(1024) DEFAULT 'NULL' COMMENT 'char(*)',
  `filter` varchar(1024) DEFAULT 'NULL' COMMENT 'bits(*)'
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT INTO `series` (`abbrev`, `catcode`, `catname`, `catkeys`, `catser`, `e_codes`, `filter`) VALUES
('AR', 'A5B31022', 'A5B31', 'A5B310', 'A5B310 (MAGYAR)', '02,22', '0b00000000000000000000000000000001'),
('AR', 'A5B31022', 'A5B41', 'A5B412', 'A5B412 (MAGYAR)', '02,22', '0b0000000000000000000000000000001'),
('AR', 'A5B31022', 'A5B41', 'A5B413D', 'A5B413D (MAGYAR)', '02,22', '0b000000000000000000000000000001'),
('EU', 'A5B31022', 'A5B31', 'A5B310', 'A5B310 (MAGYAR)', '02,22', '0b00000000000000000000000000000001'),
('EU', 'A5B31022', 'A5B41', 'A5B412', 'A5B412 (MAGYAR)', '02,22', '0b0000000000000000000000000000001'),
('EU', 'A5B31022', 'A5B41', 'A5B413D', 'A5B413D (MAGYAR)', '02,22', '0b000000000000000000000000000001')..... и т.д.



Вторая таблица:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
CREATE TABLE IF NOT EXISTS `groups` (
  `catcode` char(8) DEFAULT 'NULL' COMMENT 'char(8)',
  `secnum` char(1) DEFAULT 'N' COMMENT 'char(1)',
  `fignum_lj` varchar(1024) DEFAULT 'NULL' COMMENT 'char(*)',
  `fignum` varchar(1024) DEFAULT 'NULL' COMMENT 'char(*)',
  `figtext` varchar(1024) DEFAULT 'NULL' COMMENT 'char(*)',
  `amsindex` char(2) DEFAULT 'NU' COMMENT 'char(2)',
  `note` char(2) DEFAULT 'NU' COMMENT 'char(2)',
  `filters` varchar(1922) DEFAULT 'NULL' COMMENT 'bits(1920)',
  KEY `filters` (`filters`(333))
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT INTO `groups` (`catcode`, `secnum`, `fignum_lj`, `fignum`, `figtext`, `amsindex`, `note`, `filters`) VALUES
('A5B31022', '1', '1', '   1', 'ENGINE GASKET SET (A5B310)', '1', '10', '0b000000000000000000000000000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'),
('A5B31022', '1', '10', '  10', 'OIL PAN (TYPE 1:A5B310)', '1', '10', '0b000000000000000000000000000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110000000000000000000000000000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') и т.д.



Так вот эти две табличка связаны по catcode и filter. По catcode всё просто... а вот как связать по этому filter - хз... :)
...
Рейтинг: 0 / 0
31.07.2013, 10:18:43
    #38349691
Arhat109
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
aleksey_sql,

Н-да, как всё запущено... поля-то даже и не одинаковые вовсе... первое 1024, а второе 1920...

А Вы не смотрели КАК используется эта БД в том приложении, где она работает? Подозреваю, что "связаны" они весьма примитивно частью подстроки... причем фиксированной частью (начало, конец или как ещё). Это многое может упростить.
...
Рейтинг: 0 / 0
31.07.2013, 10:20:21
    #38349694
Arhat109
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
aleksey_sql,

и, кстати, в табличке series - поле всегда 32 бита?
...
Рейтинг: 0 / 0
31.07.2013, 10:22:02
    #38349698
deblogger
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
Один программист сделал себе переменную типа db, второй пытается ее освоить. :)
...
Рейтинг: 0 / 0
31.07.2013, 10:23:43
    #38349700
aleksey_sql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
Arhat109aleksey_sql,

Н-да, как всё запущено... поля-то даже и не одинаковые вовсе... первое 1024, а второе 1920...

А Вы не смотрели КАК используется эта БД в том приложении, где она работает? Подозреваю, что "связаны" они весьма примитивно частью подстроки... причем фиксированной частью (начало, конец или как ещё). Это многое может упростить.

как оно используется в приложении я могу понять ТОЛЬКО из выбирающихся данных. данные выбираются разные (поле filter у них разное и substr count не всегда = 1... поэтому собсно я и смотрел в сторону битовой маски).
Протрассировать запросы flextracer'ом также не удалось. Вышибает трейсер на этапе запросов связанных с этими табличками с полем filter :)
...
Рейтинг: 0 / 0
31.07.2013, 10:25:43
    #38349704
aleksey_sql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
Arhat109aleksey_sql,

и, кстати, в табличке series - поле всегда 32 бита?

нет. поле filter там тоже переменное :(
...
Рейтинг: 0 / 0
31.07.2013, 11:09:08
    #38349777
netwind
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
aleksey_sql[
Протрассировать запросы flextracer'ом также не удалось. Вышибает трейсер на этапе запросов связанных с этими табличками с полем filter :)
это что еще за фуфел? в mysql для этого есть general log. его не может вышибить.
...
Рейтинг: 0 / 0
31.07.2013, 11:12:37
    #38349784
aleksey_sql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
netwindaleksey_sql[
Протрассировать запросы flextracer'ом также не удалось. Вышибает трейсер на этапе запросов связанных с этими табличками с полем filter :)
это что еще за фуфел? в mysql для этого есть general log. его не может вышибить.

это не фуфел. это прога которая трассирует запросы с другой субд. дело в том, что я юзаю mysql уже смигрированную с другой субд.
...
Рейтинг: 0 / 0
31.07.2013, 11:58:45
    #38349890
netwind
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WHERE по битовой маске
aleksey_sql, я шучу. попробуйте включить general-log - это часть функционала mysql, который славится стабильностью. он не вылетит.
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / WHERE по битовой маске / 25 сообщений из 43, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]