LIKE %..% по полю таблицы

@lexander

Новичок
LIKE %..% по полю таблицы

Как осуществить следующий запрос?
[SQL]SELECT mods.id FROM mods,versions WHERE mod_adm LIKE '%;1;%' AND versions.mods LIKE '%;mods.id;%'[/SQL]
проблема именно в %;mods.id;%. Как подставить значение поля в LIKE?
 

SelenIT

IT-лунатик :)
По идее, как любую переменную в строку - конкатенацией: '%;' + mods.id + ';%'

Но лучше перепроектировать базу - сделать отдельную таблицу для пар "mod - version" (таблицу связей). Будет и быстрее, и правильнее.
 

Wicked

Новичок
Согласен с SelenIT, что через таблицы связей получается гораздо лучше.

Но если уж делать через зад, то используя FIND_IN_SET(). А то потом начнутся вопросы, как быть с первым/последним элементом.
 

@lexander

Новичок
Но лучше перепроектировать базу - сделать отдельную таблицу для пар "mod - version" (таблицу связей). Будет и быстрее, и правильнее.
не имеет смысла в данном случае. Вышеприведеный запрос будет выполнятся только при добавлении нового мода.
 

SelenIT

IT-лунатик :)
Wicked
Проблема первого и последнего у него, судя по тексту, "решена" лишними разделителями в начале и конце. А вот каким боком тут можно использовать FIND_IN_SET() - что-то никак не соображу. Да и зачем делать через зад, если есть нормальный общепринятый способ, позволяющий к тому же использовать индексы?
 

@lexander

Новичок
Автор оригинала: Wicked
Но если уж делать через зад, то используя FIND_IN_SET(). А то потом начнутся вопросы, как быть с первым/последним элементом.
FIND_IN_SET Возвращает значение от 1 до N, если строка str присутствует в списке strlist
Зачем? LIKE должен быть быстрее

>как быть с первым/последним элементом.
Какие проблемы? :))
 

Wicked

Новичок
SelenIT
1) судя по какому тексту? не вижу.
2) WHERE FIND_IN_SET('1', mod_adm) AND FIND_IN_SET(mods.id, versions.mods). Ессно при условии замены ';' на ','
3) как видишь, в мире довольно людей, которых тянет делать это именно через зад. Например, мотивируя тем, что им правильно то вовсе и не надо.
 

SelenIT

IT-лунатик :)
@lexander
Проблем в принципе две - невозможность использовать индексы при поиске и необходимость апдейта большого количества строковых данных при добавлении/удалении связи. Если данных у тебя немного и скорость этих операций устраивает - пользуйся на здоровье тем что есть...

Wicked
Судя по тексту вопроса. В прошлом посте @lexander как раз подтвердил мою догадку :)
А за пример с FIND_IN_SET - спасибо, но все равно imho это излишество...
 

Wicked

Новичок
@lexander
Тебя, я смотрю, интересуют проблемы производительности? ха ха.

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

@lexander

Новичок
mysql_query("... ... LIKE '%;$id;%'");

-----
Всё. Завтра перепишу всё для таблиц-связок
 

Wicked

Новичок
@lexander
ну это то понятно... а с условием versions.mods
LIKE '%;mods.id;%' ты как поступишь? :)
 

@lexander

Новичок
ну это то понятно... а с условием versions.mods
SELECT mod_ver.mod FROM mod_ver WHERE mod_ver.ver = $id

mod_ver — таблица связи модов и версий.
Аналогично adm_mod — администраторы и моды (При такой организации можно ещё выставлять каждому пользователю права на доступ к конкретному елементу)

Ключ поставил примари на оба поля(так, вроде, быстрее?).

Хе, хе. Вот как мой запросик разросся. Надеюсь, это будет быстрее аналогичного с LIKE:
[sql]SELECT mods.* FROM mods
LEFT JOIN trans_mods ON mods.id=trans_mods.id
WHERE trans_mods.id IS NULL AND mods.id IN (SELECT mod_ver.mod FROM mod_ver WHERE mod_ver.ver = $id) AND mods.id IN (SELECT adm_mod.mod FROM adm_mod WHERE adm_mod.adm = ".$portal->member['id'].")[/sql]

Чаше всего будет использоваться этот:
[sql]SELECT * FROM `trans_mods`,mods WHERE mods.id=trans_mods.id AND mods.active = 1 AND mods.id IN (SELECT mod_ver.mod FROM mod_ver WHERE mod_ver.ver = {$ver['id']})[/sql]

Что должно оказаться быстрее:
JOIN
[sql]SELECT `members_display_name` FROM `ibf_members` LEFT JOIN adm_prj ON ibf_members.id=adm_prj.adm WHERE prj =?[/sql]
или подзапрос
[sql]SELECT `members_display_name` FROM `ibf_members` WHERE id IN (SELECT adm FROM `adm_prj` WHERE prj =?)[/sql]
 

Wicked

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