2010-03-04 22 views
5

Básicamente tengo una tabla como la siguiente:¿Cómo consultar la base de datos de SQL Server 2008 para buscar el nombre y apellido y ordenar por relevancia?

CREATE TABLE Person(
    PersonID int IDENTITY(1,1) NOT NULL, 
    FirstName nvarchar(512) NOT NULL, 
    LastName nvarchar(512) NULL 
) 

y necesito encontrar los mejores n resultados basados ​​en un usuario-consulta como esta:

"Joh Smi" 

la siguiente consulta devuelve los resultados Necesito (creo) Simplemente no en el orden relevante.

SELECT 
    PersonID, FirstName, LastName 
FROM 
    Person 
WHERE 
    FirstName LIKE 'Joh%' OR 
    LastName LIKE 'Joh%' OR 
    FirstName LIKE 'Smi%' OR 
    LastName LIKE 'Smi%' 

Si los siguientes nombres estaban en la base de datos y nuestra facilidad de consulta fue "Joh SMI" los nombres deben aparecer en el siguiente orden (o similar)

  1. John Smith
  2. Johnny Smith
  3. John Jacob
  4. David Smithsonian
  5. Daniel Johnson

Espero hacerlo funcionar de forma similar a la búsqueda de amigos de autocompletar de Facebook.

Entonces, ¿cómo devuelvo las filas más relevantes n en SQL Server 2008?

Respuesta

2

Como una adición a la respuesta de los potros ... OMG

para obtener los mejores resultados de una búsqueda de texto completo es posible que desee cr eate una vista indizada que concatena los campos de nombre y apellido.

Esto le permitirá ponderar las partes individuales del nombre completo de manera más precisa.

Ejemplo de código de la siguiente manera:

CREATE VIEW [dbo].[vFullname] WITH SCHEMABINDING AS 
    SELECT personID, FirstName + ' ' + LastName AS name 
    FROM dbo.person 

    WITH ranks AS(
    SELECT FT_TBL.personid 
     ,FT_TBL.name 
     ,KEY_TBL.RANK 
    FROM dbo.vfullname AS FT_TBL 
     INNER JOIN CONTAINSTABLE(vfullname, (name), 
    'ISABOUT ("Smith" WEIGHT (0.4), "Smi*" WEIGHT (0.2), 
"John" WEIGHT (0.3), "Joh*" WEIGHT (0.1))') AS KEY_TBL 
      ON FT_TBL.personid = KEY_TBL.[KEY] 
    ) 
    SELECT 
    r.personID, 
    p.firstname, 
    p.lastname, 
    r.rank 
    FROM ranks r INNER JOIN 
    person p ON r.personID = p.personID 
    ORDER BY rank DESC; 

El CTE simplemente le permite devolver los campos Nombre y Apellidos individuales. Si no los necesita como salida, ignórelos.

1

Primero tiene que decidir qué quiere decir relevancia. Aquí está mi lista de relevancia

  1. Ambas palabras son exactamente el nombre y apellido
  2. mismo que la primera, pero inversa para
  3. Uno de ellos es la palabra completa, uno está subcadena
  4. Igual que el tercero
  5. Tanto son subcadenas. Dentro de esta se puede evaluar por la longitud de la subcadena (más medios bien)
  6. Una de ellas es la subcadena

así que recomendaría usted para crear la función que tendrá nombre y apellido y la cadena de entrada y de retorno int, o flotar accoring a las reglas, luego ordena por él.

+0

Me encanta la lista. ¿Pero cómo sería la consulta/función SQL? :-) –

+0

hey, son casi las 2 de la mañana aquí, quiero dormir :) – Andrey

+0

jaja. ok ok ... te daré un descanso. –

5

Recomiendo la aplicación de búsqueda de texto completo (FTS) por dos razones:

  1. simplificar la consulta (no debería necesitar las RUP, which'll bajo rendimiento)
  2. Utilizar el FTS rango funcionalidad - véase this article
Cuestiones relacionadas