MYSQL REGEXP/RLIKE Советы?
У меня есть таблица под названием "стипендии", в которой есть поле под названием "майоры", которое содержит основные имена, разделенные запятыми, для тех специальностей, с которыми связана стипендия.
Допустим, поле может содержать одно (или несколько разделенных запятыми) из следующих: бизнес, агробизнес, управление бизнесом, международный бизнес.
Если кто-то ищет "бизнес" в качестве основного, как я могу выбрать "бизнес" в качестве соответствия, но не другие?
Самое близкое, что я получил, - это, но я знаю, что могло бы быть и лучше - моя способность к регулярным выражениям не такая уж горячая.
SELECT scholarship_id, scholarship_award_name, scholarship_majors
FROM scholarships
WHERE scholarship_majors rlike '[, ][[:<:]]business[[:>:]][, ]'
OR scholarship_majors rlike '^[[:<:]]business[[:>:]][, ]'
OR scholarship_majors rlike '[, ][[:<:]]business[[:>:]]$'
Я пытаюсь поймать поле, если оно начинается с "бизнес" или "бизнес" или "бизнес", "бизнес", но не "бизнес-администрирование" и т. Д...
Любой совет?
3 ответа
Любой совет?
Не храните данные в разделенных запятыми списках - это денормализованные данные, и, кроме того, что их трудно выделить, они также подвержены ошибочным данным (опечатки, чувствительность к регистру...).
Определить
MAJORS
Таблица:- MAJOR_ID (первичный ключ)
- MAJOR_NAME
Используйте таблицу "многие ко многим", чтобы присоединить стипендии к одной или нескольким специальностям:
SCHOLARSHIP_MAJORS
- SCHOLARSHIP_ID (первичный ключ, внешний ключ к таблице SCHOLARSHIPS)
- MAJOR_ID (первичный ключ, внешний ключ к таблице MAJORS)
Используйте СОЕДИНЕНИЯ для получения стипендий по специальностям:
SELECT s.scholarship_id, s.scholarship_award_name, m.major_name FROM SCHOLARSHIPS s JOIN SCHOLARSHIP_MAJORS sm ON sm.scholarship_id = s.scholarship_id JOIN MAJORS m ON m.major_id = sm.major_id WHERE m.major_name IN ('a', 'b', 'c')
... если вы хотите, чтобы основные данные выводились в списке через запятую, используйте функцию GROUP_CONCAT:
SELECT s.scholarship_id,
s.scholarship_award_name,
GROUP_CONCAT(m.major_name) AS majors
FROM SCHOLARSHIPS s
JOIN SCHOLARSHIP_MAJORS sm ON sm.scholarship_id = s.scholarship_id
JOIN MAJORS m ON m.major_id = sm.major_id
WHERE m.major_name IN ('a', 'b', 'c')
GROUP BY s.scholarship_id, s.scholarship_award_name
Я смог улучшить sql, запретив такие альфа-символы, как:
SELECT scholarship_id, scholarship_award_name, scholarship_majors
FROM scholarships
WHERE scholarship_majors rlike '[, ][^a-z][[:<:]]business[[:>:]][^a-z][, ]'
OR scholarship_majors rlike '^[[:<:]]business[[:>:]][^a-z][, ]'
OR scholarship_majors rlike '[, ][^a-z][[:<:]]business[[:>:]]$'
Это похоже на то, на что я надеюсь!
Все еще ищу какой-либо совет по улучшению этого оператора SQL.
Я потратил некоторое время на борьбу с регулярным выражением, поскольку база данных, с которой я имею дело, имеет пару полей типа CSV.
Сравнительный анализ показал, что это хороший способ с более простым синтаксисом:
SELECT * FROM table WHERE FIND_IN_SET('string', my_field)
Рассматриваемое поле ДОЛЖНО быть строковым полем CSV. Идеальное решение для моей проблемы. Да, я признаю, что множество таблиц является более нормализованным.