Я новичок в программировании SQL.
У меня есть таблица, где поля id
, position
, category
, location
, salary range
, description
, refno
.
Я хочу реализовать поиск по ключевым словам из внешнего интерфейса. Ключевое слово может находиться в любом из полей приведенной выше таблицы.
Это запрос, который я пробовал, но он состоит из множества повторяющихся строк:
SELECT
a.*,
b.catname
FROM
job a,
category b
WHERE
a.catid = b.catid AND
a.jobsalrange = '15001-20000' AND
a.jobloc = 'Berkshire' AND
a.jobpos LIKE '%sales%' OR
a.jobloc LIKE '%sales%' OR
a.jobsal LIKE '%sales%' OR
a.jobref LIKE '%sales%' OR
a.jobemail LIKE '%sales%' OR
a.jobsalrange LIKE '%sales%' OR
b.catname LIKE '%sales%'
Для одного ключевого слова в полях VARCHAR вы можете использовать LIKE
:
SELECT id, category, location
FROM table
WHERE
(
category LIKE '%keyword%'
OR location LIKE '%keyword%'
)
Для описания вы обычно лучше добавляете полный текстовый индекс и выполняете Полнотекстовый поиск (только MyISAM):
SELECT id, description
FROM table
WHERE MATCH (description) AGAINST('keyword1 keyword2')
SELECT
*
FROM
yourtable
WHERE
id LIKE '%keyword%'
OR position LIKE '%keyword%'
OR category LIKE '%keyword%'
OR location LIKE '%keyword%'
OR description LIKE '%keyword%'
OR refno LIKE '%keyword%';
Вы можете найти еще один более простой вариант в теме: Match Against.. с более подробной информацией в 11.9.2. Булевые полнотекстовые поисковые запросы
Это на всякий случай, если кому-то нужен более компактный вариант. Это потребует создания индекса таблицы FULLTEXT в таблице, что может быть выполнено легко.
Информация о том, как создавать индексы (MySQL): Индексирование и поиск MySQL FULLTEXT
В индексе FULLTEXT
вы можете указать более одного столбца, результатом будет выражение SQL с индексом с именем search
:
SELECT *,MATCH (`column`) AGAINST('+keyword1* +keyword2* +keyword3*') as relevance FROM `documents`USE INDEX(search) WHERE MATCH (`column`) AGAINST('+keyword1* +keyword2* +keyword3*' IN BOOLEAN MODE) ORDER BY relevance;
Я пробовал с несколькими столбцами, без везения. Несмотря на то, что в индексах разрешено использовать несколько столбцов, для каждого столбца, который будет использоваться с Match/Against Statement, вам нужен индекс.
В зависимости от ваших критериев вы можете использовать любые параметры.
Лично я не использовал бы сравнение строк LIKE
в поле ID или в любом другом числовом поле. Для поиска ID # " 216" не имеет смысла возвращать 16 216, 216 51, 3 216 087, 53 216 68... и т.д. и т.д.; также с зарплатой.
Кроме того, если вы хотите использовать подготовленные инструкции для предотвращения инъекций SQL, вы должны использовать строку запроса, например:
SELECT * FROM job WHERE `position` LIKE CONCAT('%', ? ,'%') OR ...
В идеале, есть таблица ключевых слов, содержащая поля:
Keyword
Id
Count (possibly)
с индексом по ключевому слову. Создайте триггер insert/update/delete в другой таблице, чтобы при изменении строки каждое ключевое слово извлекалось и помещалось в (или заменялось) в этой таблице.
Вам также понадобится таблица слов, которая не будет считаться ключевыми словами (если и так, но...).
Таким образом, вы получите максимальную скорость для запросов, требующих поиска ключевых слов, и вы можете реализовать (относительно легко) более сложные запросы, такие как "содержит Java и RCA1802".
"LIKE"
будут работать, но они также не будут масштабироваться.
Я объясню метод, который обычно предпочитает:
Прежде всего, вам нужно принять во внимание, что для этого метода вы будете жертвовать памятью с целью получения скорости вычислений. Во-вторых, вы должны иметь право редактировать структуру таблицы.
1) Добавьте поле (я обычно называю его "дайджест" ), где вы храните все данные из таблицы.
Поле будет выглядеть так:
"n-n1-n2-n3-n4-n5-n6-n7-n8-n9" и т.д., где n - одно слово
Я достигаю этого, используя регулярное выражение thar заменяет "на" -". Это поле является результатом того, что все данные таблицы "перевариваются" в одной строке sigle.
2) Используйте оператор LIKE% keyword% в поле дайджест:
SELECT * FROM table WHERE digest LIKE %keyword%
вы даже можете создать qUery с небольшим циклом, чтобы вы могли одновременно искать несколько ключевых слов:
SELECT * FROM table WHERE
digest LIKE %keyword1% AND
digest LIKE %keyword2% AND
digest LIKE %keyword3% ...
Я знаю, что это немного поздно, но я сделал это в нашем приложении. Надеюсь, это поможет кому-то. Но это работает для меня:
SELECT * FROM `landmarks` WHERE `landmark_name` OR `landmark_description` OR `landmark_address` LIKE '%keyword'
OR `landmark_name` OR `landmark_description` OR `landmark_address` LIKE 'keyword%'
OR `landmark_name` OR `landmark_description` OR `landmark_address` LIKE '%keyword%'