Использование mysql concat () в предложении WHERE? - PullRequest
41 голосов
/ 20 ноября 2008

Я хотел бы найти в моей таблице столбец с именами и столбец с фамилиями. В настоящее время я принимаю поисковый запрос из поля и сравниваю его с обоими столбцами, по одному с

    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%';

Какой совет?

РЕДАКТИРОВАТЬ: Имя, с которым я тестирую, "Ларри Смит". БД хранит «Larry» в столбце «first_name» и «Smith» в столбце «last_name». Данные чистые, лишних пробелов нет, а поисковый запрос обрезается слева и справа.

РЕДАКТИРОВАТЬ 2: Я попробовал ответ Роберта Гэмбла сегодня утром. Его очень похоже на то, что я бегал прошлой ночью. Я не могу это объяснить, но сегодня утром это работает. Единственное различие, о котором я могу думать, это то, что прошлой ночью я запустил функцию concat в качестве третьего сегмента «или» моего поискового запроса (после просмотра first_name и last_name). Этим утром я проверил это как последний сегмент после просмотра вышеупомянутого так же как адресов и названий компаний.

Работает ли функция mysql в конце запроса лучше, чем в середине?

Ответы [ 7 ]

80 голосов
/ 20 ноября 2008

То, что у вас есть, должно работать, но может быть уменьшено до:

select * from table where concat_ws(' ',first_name,last_name) 
like '%$search_term%';

Можете ли вы привести пример имени и условия поиска, где это не работает?

11 голосов
/ 10 февраля 2012

Обратите внимание, что поисковый запрос теперь чувствителен к регистру.

При использовании

SELECT * FROM table WHERE `first_name` LIKE '%$search_term%'

Будет соответствовать как "Larry", так и "larry". С этим concat_ws он вдруг станет чувствительным к регистру!

Это можно исправить с помощью следующего запроса:

SELECT * FROM table WHERE UPPER(CONCAT_WS(' ', `first_name`, `last_name`) LIKE UPPER('%$search_term%')

Редактировать: обратите внимание, что это работает только на недвоичных элементах. Смотрите также mynameispaulie's answer .

4 голосов
/ 01 ноября 2012

Люку:

Я согласен с вашим ответом, хотя я хотел бы добавить, что UPPER работает только на недвоичных элементах. Если вы работаете, скажем, со столбцом AGE (или любым другим числовым), вам нужно выполнить преобразование CAST, чтобы заставить функцию UPPER работать правильно.

SELECT * FROM table WHERE UPPER(CONCAT_WS(' ', first_name, last_name, CAST(age AS CHAR)) LIKE UPPER('%$search_term%');

Простите, что не ответил на ответ Люка напрямую, но я не мог понять, как это сделать. Если администратор может переместить мой пост, сделайте это.

3 голосов
/ 20 ноября 2008
SELECT *,concat_ws(' ',first_name,last_name) AS whole_name FROM users HAVING whole_name LIKE '%$search_term%'

... это, вероятно, то, что вы хотите.

1 голос
/ 24 февраля 2012

вы можете сделать это (работать в MySQL), вероятно, другой SQL тоже .. просто попробуйте это:

select * from table where concat(' ',first_name,last_name) 
    like '%$search_term%';
1 голос
/ 20 ноября 2008

Есть несколько вещей, которые могут помешать - ваши данные чисты?

Может быть, у вас есть пробелы в конце поля имени, что означает, что у вас есть два пробела между именем и фамилией, когда вы их объединяете? Использование 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);
0 голосов
/ 24 ноября 2014

Вы можете попробовать это:

select * FROM table where (concat(first_name, ' ', last_name)) = $search_term;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...