Я хотел бы выполнить поиск в своей таблице, имеющей столбец имен и столбец фамилий. В настоящее время я принимаю поисковый запрос из поля и сравниваю его с обоими столбцами по одному с
select * from table where first_name like '%$search_term%' or
last_name like '%$search_term%';
Это отлично работает с условиями поиска по одному слову, но набор результатов включает всех с именем «Ларри». Но если кто-то вводит имя, затем пробел, а затем фамилию, мне нужен более узкий результат поиска. Я безуспешно пробовал следующее.
select * from table where first_name like '%$search_term%' or last_name
like '%$search_term%' or concat_ws(' ',first_name,last_name)
like '%$search_term%';
Любой совет?
Обновлено: Я тестирую имя «Ларри Смит». База данных хранит «Ларри» в столбце «first_name» и «Smith» в столбце «last_name». Данные чистые, без лишних пробелов, а поисковый запрос обрезан слева и справа.
Обновлено еще раз: Я попробовал ответить Роберта Гэмбла сегодня утром. Его очень похоже на то, что я бегал прошлой ночью. Я не могу это объяснить, но сегодня утром это работает. Единственное отличие, о котором я могу думать, заключается в том, что вчера вечером я запустил функцию concat как третий сегмент "или" моего поискового запроса (после просмотра first_name и last_name). Сегодня утром я запустил его как последний сегмент после просмотра вышеупомянутого, а также адресов и названий компаний.
Работает ли функция mysql в конце запроса лучше, чем в середине?






SELECT *,concat_ws(' ',first_name,last_name) AS whole_name FROM users HAVING whole_name LIKE '%$search_term%'
... наверное, то, что вы хотите.
То, что у вас есть, должно работать, но его можно свести к:
select * from table where concat_ws(' ',first_name,last_name)
like '%$search_term%';
Не могли бы вы привести пример имени и поискового запроса, где это не работает?
Поддерживается ли этот синтаксис или что-то подобное во всех базах данных? Упоминается ли это в стандарте SQL?
Есть ли способ сделать это, хотя и по-разному во всех базах данных?
Как насчет того, чтобы сделать это в двух разных таблицах? Моя ситуация в разных таблицах, поэтому.
Вы знаете, можно ли в этом запросе использовать индексы?
Есть несколько вещей, которые могут помешать - чисты ли ваши данные?
Может быть, у вас есть пробелы в конце поля имени, что означает, что у вас есть два пробела между именем и фамилией, когда вы их объединяете? Использование trim (first_name) / trim (last_name) исправит это, хотя реальное исправление - обновить ваши данные.
Вы также можете это сопоставить, где встречаются два слова, но не обязательно вместе (при условии, что вы находитесь в php - что предполагает переменная $ search_term)
$whereclauses=array();
$terms = explode(' ', $search_term);
foreach ($terms as $term) {
$term = mysql_real_escape_string($term);
$whereclauses[] = "CONCAT(first_name, ' ', last_name) LIKE '%$term%'";
}
$sql = "select * from table where";
$sql .= implode(' and ', $whereclauses);
Обратите внимание, что поисковый запрос теперь чувствителен к регистру.
Когда используешь
SELECT * FROM table WHERE `first_name` LIKE '%$search_term%'
Он будет соответствовать как «Ларри», так и «Ларри». С этим concat_ws он внезапно станет чувствительным к регистру!
Это можно исправить, используя следующий запрос:
SELECT * FROM table WHERE UPPER(CONCAT_WS(' ', `first_name`, `last_name`) LIKE UPPER('%$search_term%')
Обновлено: обратите внимание, что это работает только с недвоичными элементами. См. Также ответ mynameispaulie.
В случае, если вы объединяете целочисленные поля, чувствительность к регистру также может быть результатом ошибки в MySQL до версии 5.5 - см. Этот отвечать
вы можете сделать это (работать в mysql), вероятно, другой SQL тоже .. просто попробуйте это:
select * from table where concat(' ',first_name,last_name)
like '%$search_term%';
Люку:
Я согласен с вашим ответом, хотя хотел бы добавить, что UPPER работает только с недвоичными элементами. Если вы работаете, скажем, со столбцом AGE (или любым другим числом), вам необходимо выполнить преобразование CAST, чтобы функция UPPER работала правильно.
SELECT * FROM table WHERE UPPER(CONCAT_WS(' ', first_name, last_name, CAST(age AS CHAR)) LIKE UPPER('%$search_term%');
Простите меня за то, что я не ответил на ответ Люка напрямую, но, хоть убей, я не мог понять, как это сделать. Если администратор может переместить мой пост, сделайте это.
Добро пожаловать в Stack Overflow! Для оставления комментариев требуется 50 репутации. Да, посетителей раздражает то, что они могут добавить что-то полезное, но это также сокращает ненужную болтовню. Публикация того, что должно быть комментарием в качестве ответа, в любом случае не одобряется, но, поскольку вы предоставили информацию, имеющую отношение к решению проблемы, это, вероятно, нормально.
Пятьдесят - довольно высокий предел: / В любом случае, я поддержал ваш ответ (+10 репутации) и связал его в своем сообщении. Спасибо за дополнение :)
В случае, если вы объединяете целочисленные поля, чувствительность к регистру также может быть результатом ошибки в MySQL до версии 5.5 - см. Этот отвечать
Вы можете попробовать это:
select * FROM table where (concat(first_name, ' ', last_name)) = $search_term;
Вам нужно будет добавить скобки к вашему "$ search_term"
Это также требует, чтобы пользователь вводил имя точно, а не частичные совпадения (пример: «Пэт» соответствует «Пэт» и «Патрик»).
Я только что запустил ту версию, с которой у вас возникли проблемы, и она мне подходит.