Я хотел бы выполнить поиск в моей таблице с столбцом с именами и столбцом с именами. В настоящее время я принимаю поисковый запрос из поля и сравниваю его с обоими столбцами, по одному с
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%';
Любые советы?
EDIT: Название, с которым я тестирую, - "Ларри Смит". ДБ хранит "Ларри" в столбце "first_name" и "Smith" в столбце "last_name". Данные чистые, без лишних пробелов, а поисковый запрос обрезается влево и вправо.
РЕДАКТИРОВАТЬ 2: Я попробовал ответить Роберту Гэмбл сегодня утром. Его очень похоже на то, что я бежал прошлой ночью. Я не могу это объяснить, но сегодня утром это работает. Единственное различие, о котором я могу думать, это то, что вчера вечером я запустил функцию concat как третий "или" сегмент моего поискового запроса (после просмотра first_name и last_name). Сегодня утром я провел его как последний сегмент, просмотрев выше, а также адреса и названия компаний.
Работает ли функция mysql в конце запроса лучше, чем в середине?
Что вам нужно, но можно свести к:
select * from table where concat_ws(' ',first_name,last_name)
like '%$search_term%';
Можете ли вы указать имя примера и поисковый запрос, где это не работает?
Обратите внимание, что поисковый запрос теперь чувствителен к регистру.
При использовании
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.
Люку:
Я согласен с вашим ответом, хотя хотел бы добавить, что UPPER работает только с недвоичными элементами. Если вы работаете с столбцом AGE (или любым числом), вам необходимо выполнить преобразование CAST, чтобы функция UPPER работала правильно.
SELECT * FROM table WHERE UPPER(CONCAT_WS(' ', first_name, last_name, CAST(age AS CHAR)) LIKE UPPER('%$search_term%');
Прости меня за то, что я не отвечал на Люка напрямую, но ради жизни я не мог понять, как это сделать. Если администратор может переместить мой пост, сделайте это.
SELECT *,concat_ws(' ',first_name,last_name) AS whole_name FROM users HAVING whole_name LIKE '%$search_term%'
... возможно, то, что вы хотите.
вы можете сделать это (работа в mysql), вероятно, другой SQL тоже.. просто попробуйте это:
select * from table where concat(' ',first_name,last_name)
like '%$search_term%';
Есть несколько вещей, которые могут мешать - ваши данные чистые?
Может быть, у вас есть пробелы в конце поля первого имени, что означает, что у вас есть два пробела между первым и последним, когда вы их объединяете? Использование 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 (concat(first_name, ' ', last_name)) = $search_term;