поиск человека по имени в базе данных — MySQL

#mysql #sql

#mysql #sql

Вопрос:

В моей таблице я храню имя в fName столбце и фамилию в lName столбце, теперь мне нужно выполнить поиск по ним с помощью запроса, но я не знаю SQL!

пример

    lName | fName  
-----------------
Tendulkar| Sachin   
Ganguly  | Sourav   
Khan     | Zaheer  
Dhoni    | Mahendra Singh  
  

Пользователь должен получить MAHENDRA SINGH DHONI, если он ищет Mahendra Dhoni!

Комментарии:

1. Определить поиск «махендра дхони»? Означает ли это, что вы знаете фамилию конкретно? Означает ли это, что вы знаете полную строку только от пользователя? Означает ли это, что у вас есть и имя, и фамилия?

Ответ №1:

 select concat(fName,' ',lName) fullname
from tbl
where concat(' ',fName,' ',lName,' ') like '% Mahendra %'
  and concat(' ',fName,' ',lName,' ') like '% dhoni %'
  

Это, безусловно, положит конец любым надеждам на хорошо выполняемый запрос

Вариация на тему

 select concat(fName,' ',lName) fullname
from tbl
where (concat(fName,' ',lName) like '%Mahendra%dhoni%'
    or concat(lName,' ',fName) like '%Mahendra%dhoni%')
  

2-я версия не заботится о полном сопоставлении частей, например, dhoni будет соответствовать madhonie


Оба этих запроса находят имя правильно. Обратите внимание, что перед именем и после него есть % для сопоставления, а также % для каждого пробела в имени.

 create table tbl (fname varchar(100), lname varchar(100));
insert tbl select 'Mahendra singh', 'dhoni';

select concat(fName,' ',lName) fullname
from tbl
where (concat(fName,' ',lName) like '%Mahendra%dhoni%'
    or concat(lName,' ',fName) like '%Mahendra%dhoni%');

select concat(fName,' ',lName) fullname
from tbl
where (concat(fName,' ',lName) like '%dhoni%Mahendra%'
    or concat(lName,' ',fName) like '%dhoni%Mahendra%');
  

Комментарии:

1. ваш запрос работает, если я ищу Mahendra Dhoni, но не работает, если я ищу Dhoni Mahendra, мне нужно создать функцию поиска человека, такую как Facebook, orkut, где пользователь может выполнять поиск по фамилии, я думаю, вы можете помочь!

2. я не знаю, но для Mahendra Dhoni это сработало идеально, но не для Dhoni Mahendra [возвращает пустой результирующий набор]

3. @Richard aka cyberkiwi нет, сэр, возникает та же проблема:(

4. мне нужно написать SQL, который возвращает тот же результат для БИЛЛА ГЕЙТСА и GATES BILL [точно так же, как Facebook или kut делают]

5. @Sourav / Я дважды проверил и протестировал это

Ответ №2:

Вам неясен характер входных данных для поиска и, в частности, уровень гибкости. Во-первых, предоставляется ли пользователю два поля для имени и фамилии или только одно поле поиска? Если первое, то быстрым решением было бы:

 Select concat( fname, ' ', lname)
From MyTable
Where lname Like 'dhoni%'
    And fname Like 'mahendra%'
  

Приведенный выше запрос выполняет поиск только там, где первая часть значения столбца начинается со значений поиска. Однако, если пользователь может ввести что угодно в одно окно поиска, это сложнее. Если предполагается, что пользователь ввел <name part> space <name part> , то одним из решений, которое решает эту конкретную проблему, когда пользователь вводит только два слова, является разделение на пробел и запуск чего-то вроде:

 Select concat( fname, ' ', lname)
From MyTable
Where ( lname Like '%dhoni%' And fname Like '%mahendra%' )
    Or ( lname Like '%mahendra%' And fname Like '%dhoni%' )
  

Однако этот запрос будет выполняться ужасно, потому что он заставляет систему сканировать всю таблицу каждый раз, когда он выполняется. Кроме того, что происходит, когда они вводят в ваш поиск имя, состоящее из трех частей, например, Mahendra Singh Dhoni ? Просто слишком много крайних случаев, чтобы это было выполнимо IMO. Правильное решение — получить механизм полнотекстового индексирования, такой как Lucene, который создаст индекс по обоим столбцам и оценит качество соответствия.

Lucene

Комментарии:

1. ваш 2-й запрос сработал, и вы пишете, что для 3 или более слов sql прерывается: ( я создаю facebook или подобную функцию поиска с помощью PHP / MySQL, вы можете мне в этом помочь?

2. @Sourav — Решение — это поисковая система. Имейте в виду, что вы используете пробел в качестве разделителя слов. Там могут быть дефисы, апострофы и так далее. Также следует отметить, что поиск на обратной стороне имен, вероятно, не всегда будет корректным. Может возникнуть ситуация, когда «Smyth Bob» существует отдельно от «Bob Smyth». Поисковая система, которая обеспечивает ранжирование, является правильным решением IMO.

Ответ №3:

Я предполагаю, что ваши входные данные взяты из двух разных текстовых полей, и, надеюсь, вы используете хранимую процедуру :).

 declare @input1 nvarchar(50)
declare @input2 nvarchar(5)
set @input1 = 'Mahendra'
set @input2 = 'Dhoni'

select upper((fname   ' '   lname)) as 'FullName' 
from customer
where fname like '%'   @input1   '%'
or fname like '%'   @input1   '%'
or lname like '%'   @input2   '%'
or lname like '%'   @input2   '%'
  

Если у вас есть 1 поле ввода, вы захотите разделить поисковый запрос пробелом и перебирать поисковые запросы по столбцам fname и lname, используя синтаксис like ‘%term%’.

Другим способом было бы создать хранимую процедуру, которая добавляла бы fname и lname вместе и выполняла сопоставление soundex. здесь вы сопоставляете свой поисковый запрос со звучанием слова в таблице. Google должен помочь, это довольно просто.

Ответ №4:

Я предполагаю, что у вас есть 2 входных данных, и вы получаете только часть первого имени. Если это верно, то будет работать следующее:

 select concat(fname, ' ', lname)
  from yourtable
 where substring(fname, 1, 5) = 'mahen'
   and lname = 'dhoni'
  

Преимущество этого подхода в том, что он будет использовать индексы в столбце (столбцах) или комбинированный индекс, тогда как like запросы всегда выполняют полное сканирование таблицы.

Вы также можете проверить поисковую систему, такую как sphinx или solr, когда вы действительно не знаете, какие данные вы получаете, поскольку они гораздо более гибкие, чем запросы к базе данных.

Комментарии:

1. Если вы прочтете комментарии под моим ответом, вы увидите, что OP хочет именно то, что он хочет — не какую-то урезанную подстроку, «начинающуюся с» поиска, и, конечно, не нужно выбирать между фамилией / именем (поиск должен выполняться в обоих направлениях). Дайте мне знать, когда вы сможете улучшить мой запрос, учитывая те же ограничения.

2. Я не знаю насчет Facebook, но если вы искали «ary» в Orkut, вы получите совпадения типа «D!NE $# C #aud #ary».

3. @Richard Во-первых, я четко объяснил параметры моего решения, которое прекрасно, но в любом случае благодарю за голосование «против». Реальное решение — это поисковая система, как я уже говорил, если у вас есть строка в нескольких столбцах базы данных. Что вы хотели сказать об Orkut и чем это отличается от того, что выдал бы ваш запрос, если бы данные были в базе данных, кстати?

4. @greg назовите мне техническую причину, почему это плохой ответ?

5. @wes / Если вы придерживаетесь подхода переопределения требований до тех пор, пока не сможете ответить на них тривиально … тогда у вас интересный подход. Мое замечание об Orkut (я думал, что выразился ясно) заключается в том, что он выполняет поиск по содержанию по любому имени и фамилии, а не только по началу любого из них . Не только это, но и SUBSTRING не будет использовать индекс, но, например, ‘mahen%’ будет