SQLinfo.ru - Все о MySQL Webew.ru: теория и практика веб-технологий

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 01.04.2009 01:44:52

Ket3er
Участник
Зарегистрирован: 01.04.2009
Сообщений: 4

Как правильно сравнивать множества SET?

Доброй ночи.
Не подскажете, как можно решить такую проблемку:
Есть некая табличка:

*   id  *  list1    *  list2    *
*------*---------*----------*
*   1   *   2,4,5 *   5,12   *
*   2   *    6     *   8,30   *
*   3   *   3,7   *    7,9    *
*   4   *   4      *   1,15     *

У list1 и list2 типы полей - SET, с возможными значениями от 1 до 32

Требуется для определенной записи (допустим, с id 1) найти записи, у которых среди значений их полей list1 нет значений, совпадающих со значениями поля list2 записи с id 1

Закавыка в том, что если сравнивать побитово поля list1 и list2, принадлежащие одной и той же записи:

SELECT * FROM table WHERE list1 & list2 = 0

то все работает (результатом будут записи с номерами 2 и 4)

а если сравнивать list2 записи c номером 1 (допустим) с list1 остальных записей то результат такого запроса будет уже некорректным:

SELECT * FROM table WHERE list1 & (SELECT list2 FROM table WHERE id=1 LIMIT 1) = 0

т.е., в результате будут и записи, у которых значения множеств list1 совпадают со значениями множества list2 записи с номером 1

Не подскажете, где косячу? Может вложенный запрос еще как-то конвертить надо?

Неактивен

 

#2 01.04.2009 04:01:13

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Как правильно сравнивать множества SET?

Ну, видимо, надо добавить соотв. условие:

SELECT * FROM table WHERE id !=1 AND list1 & (SELECT list2 FROM table WHERE id=1 LIMIT 1) = 0

Неактивен

 

#3 01.04.2009 04:42:33

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Как правильно сравнивать множества SET?

Еще можно так (видимо, лучше, чем предыдущий вариант):

SELECT t1.*
FROM table AS t1, table AS t2
WHERE t1.id = 1 AND t2.id != 1 AND (t1.list2 & t2.list1) = 0

Вот, насчет побитовых операций с типом SET интересная статья есть:
http://dev.mysql.com/tech-resources/art … atype.html

Неактивен

 

#4 01.04.2009 16:36:51

Ket3er
Участник
Зарегистрирован: 01.04.2009
Сообщений: 4

Re: Как правильно сравнивать множества SET?

LazY

Спасибо за ссылку на статью. Прочтение породило ряд экспериментов, но результат по-прежнему не соответствует ожидаемому

сейчас табличка выглядит так

*  id  *    list1  *    list2   *
*  0   *    a5    *             *
*  1   *    a4    *   a4,a7  *
*  2   *           *   a3,a5  *

И по-прежнему, когда я пытаюсь для записи 2 найти записи, у которых значения list1 не содержатся в ее множестве list2, в результате запросв получаю либо все три записи, либо только 2-ю, вопреки ожидаемому результату 1 и 2

последний запрос выглядит уже так:

SELECT * FROM db_op_account WHERE BINARY LPAD(BIN(set_cat+0),32,'0') & (SELECT LPAD(BIN(set_blackcat+0),32,'0') FROM db_op_account WHERE id_account=21) = 0

толку по прежнему 0 sad

Неактивен

 

#5 02.04.2009 14:00:16

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Как правильно сравнивать множества SET?

А пробовали просто представлять все это в бинарной форме? Кажется, это все решается
на уровне булевой логики очень легко.

Если нужно «все значения list1 не содержатся в list2», то
SELECT id FROM tablename WHERE NOT (list1 & list2);

Если нужно «хотя бы одно значение list1 не содержится в list2», то
SELECT id FROM tablename WHERE NOT ((list1 & list2) ^ list2);

Неактивен

 

#6 03.04.2009 00:42:51

Ket3er
Участник
Зарегистрирован: 01.04.2009
Сообщений: 4

Re: Как правильно сравнивать множества SET?

paulus

Пробовал, но почему-то не могу нормальный результат сравнения получить. Т.е. если поочередно сравниваются list1 и list2, принадлежащие одной записи, то все просто отлично.
(запрос вида: SELECT * FROM table WHERE list1 & list2 = 0)

Но если сравнивать list2 какой-то конкретной записи поочередно с list1 каждой записи, то ерунда какая-то получается
(запрос вида: SELECT * FROM table WHERE list1 & (SELECT list2 FROM table WHERE id=2 LIMIT 1) = 0)

Прямо тупик какой-то

Неактивен

 

#7 03.04.2009 17:57:24

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Как правильно сравнивать множества SET?

Стоп, а вы не одну и ту же запись сравниваете? Я так по примерам приводимым понял, что одну и ту же.

Если задача именно «для конкретной записи», то нужно еще объединение с собой.
SELECT .. FROM tablename t1, tablename t2 WHERE t1.id = .. AND t2.list2 & t1.list1.
Потребует отдельные ключики на id и list2. Без второго можно, впрочем, и обойтись, т.к. в любом случае
будет однократное сканирование таблицы, но с ключом будет using index.

Неактивен

 

#8 04.04.2009 01:24:57

Ket3er
Участник
Зарегистрирован: 01.04.2009
Сообщений: 4

Re: Как правильно сравнивать множества SET?

!!!!!!!!!!!!!!! Работает!!!!!!!!!!!!!!!!!!

paulus, БОЛЬШОЕ СПАСИБО! Уф-ф, прям гора с плеч...

И ведь LazY тоже такую конструкцию запроса подсказывал, но видать я попутал с расстановкой t1 и t2, потому как результат меня совсем не устраивал.

СПАСИБО!

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson