#mysql
Есть таблица учеников: id | name | addr | langs | times | ages 1 | Иван | Киев;Москва | рус;укр | пн;пт | 4 2 | Петр | Харьков;Москва | рус | пт | 4 3 | Олег | Рига | рус;лит | пн;вт | 5 ....... и т.д. Из этих данных нужно собрать группу- т.е. выбрать из базы учеников с: Одним городом(пример: Москва - подходят Иван и Петр) Одним языком(пример: рус - все подходят) Одним днем недели(аналогично) Одним возрастом. Один момент: Если идет "подбор" по Москве, например, то подойдут те, у которых указан город Москва+ могут "иметь" и другие города. Также и по другим полям Как тут лучше поступить? А то пока в голову приходят только идиотские решения
Ответы
Ответ 1
Вам нужна команда FIND_IN_SET(). Если использовать Ваши критерии, то Одним городом(пример: Москва - подходят Иван и Петр) надо искать так: FIND_IN_SET('Москва', addr)>0 Одним языком(пример: рус - все подходят): FIND_IN_SET('рус', langs)>0 Проблема лишь в том, что FIND_IN_SET() использует запятую, как разделитель. Т.е. Вам придется еще REPLACE() добавить. Получается, что все москвичи + рус + пт будет так: SELECT * FROM table WHERE FIND_IN_SET('Москва', REPLACE(addr, ';', ','))>0 AND FIND_IN_SET('рус', REPLACE(langs, ';', ','))>0 AND FIND_IN_SET('пт', REPLACE(times, ';', ','))>0 Однако, @AlexceiShimakov прав: описанный Вами вид структуры базы не самый лучший. Запросы, особенно, если база большая, будут большие, сложные и длинные. Если у Вас есть возможность менять структуру - очень подумайте над этим. Ну а про необходимость индексов на всех поисковых полях я вообще молчу. :)Ответ 2
Хранить города, где проживает студент через разделитель, плохая идея, лучше создать дочернюю таблицу "Города" и связать каждый город со студентом. Про остальные поля то же самое(там где данные с разделителем). После вынесения всех данных с разделителем в дочернюю таблицу, вы можете использовать обычный select c where, где вы можете отфильтровывать данные по городам, по возрастам. Если у вас нет возможности вынести данные в отдельную дочернюю таблицу, то для текущей таблицы я бы использовал функции https://stackoverflow.com/questions/14606900/mysql-create-a-simple-function, Функции можно использовать в операторе where, также как обычные условия, внутри функций парсил бы поле с разделителем, получал бы массив значений, искал среди массива переданный аргумент(например, какой-то конкретный город), и возвращал бы результат, найдено ли значение в поле.Ответ 3
1.Если лень парсить и у вас ограниченный список городов/языков или что-то еще, воспользуйтесь функцией сравнения строк like, например: select * where concat(';',addr,';') like '%;Москва;% 2.На будущее - да, не храните так значения лучше, а выносите в отдельную таблицу, или парсите заранее. 3.Для понимания зачем и почему - советую ознакомиться с нормальными формами реляционных бд.
Комментариев нет:
Отправить комментарий