#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.Для понимания зачем и почему - советую ознакомиться с нормальными формами реляционных бд.
Комментариев нет:
Отправить комментарий