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 ответа

Любой совет?

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

  1. Определить MAJORS Таблица:

    • MAJOR_ID (первичный ключ)
    • MAJOR_NAME
  2. Используйте таблицу "многие ко многим", чтобы присоединить стипендии к одной или нескольким специальностям:

    SCHOLARSHIP_MAJORS

    • SCHOLARSHIP_ID (первичный ключ, внешний ключ к таблице SCHOLARSHIPS)
    • MAJOR_ID (первичный ключ, внешний ключ к таблице MAJORS)
  3. Используйте СОЕДИНЕНИЯ для получения стипендий по специальностям:

    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. Идеальное решение для моей проблемы. Да, я признаю, что множество таблиц является более нормализованным.

Другие вопросы по тегам