2009-03-25 9 views
7

escribí esta consulta SQL para buscar en una tabla:¿Cómo hacer que una consulta de búsqueda SQL sea más poderosa?

SELECT * FROM TableName WHERE Name LIKE '%spa%' 

La tabla contienen estos fila por ejemplo:

  1. Space Company.
  2. Complejo de balneario.
  3. Hotel spa.
  4. Repuestos.
  5. WithoutTheKeyword.

Quiero saber cómo editar esta consulta por lo que devuelve los resultados ordenados así:

2 Spa resort

3 Spa hotel

1 Space Company

4 Spare Parts

son las partidas que contienen la palabra exacta primero y luego los que como.

Respuesta

10

algo así como

Select * from TableName where Name Like 'Spa%' 
ORDER BY case when soundex(name) = soundex('Spa') then '1' else soundex(name) end 

debería funcionar bien.

realidad esto va a funcionar mejor

Select * from TableName where Name Like 'Spa%' 
ORDER BY DIFFERENCE(name, 'Spa') desc; 

Fwiw Hice algunas pruebas rápidas y si 'Nombre' está en una NONCLUSTERED ÍNDICE SQL va a utilizar el índice y no hace un recorrido de tabla. Además, LIKE parece usar menos recursos que charindex (que arroja resultados menos deseables). Probado en sql 2000.

+0

escribes "soundex (name) = soundex ('Spa')", en soundex (nombre) ¿cuál es el nombre igual o debo escribir esto me gusta? –

+0

"Nombre" es el nombre de campo –

+0

para la primera secuencia de comandos que escribió, siempre me da este error: "La conversión falló al convertir el valor varchar 'L000' a tipo de datos int." –

-1

Esto debería funcionar:

Select * from TableName where Name Like '%spa%' 
ORDER BY Name 
+0

El problema es que él quiere ordenar por la calidad del partido, no tanto por la coincidencia. Ordenar por nombre no hará lo que quiera. –

1

Lo que sigue debe hacer lo necesario, pero es ineficiente, haciendo dos casillas de la tabla completa y también depende de su correspondencia exacta delimitado por espacios. Creo que la indexación de FullText ayudaría, pero eso tiene sus propios gastos generales.

select distinct * from 
(
Select * from TableName 
    where CHARINDEX('spa ', Name) > 0 
    or CHARINDEX(' spa', Name) > 0 
Union 
Select * from TableName 
    where Name Like '%spa%' 
) 
5

¿Se da cuenta, supongo, de que su esquema prácticamente elimina la utilidad de los índices para este tipo de consultas?

Un gran problema es su "LIKE '% spa%'". Cualquier tecla "LIKE" que comience con un comodín es un escaneo automático de tabla.


EDIT: leí tu pregunta a decir que no hay un solo campo, Nombre, con valores de campo algo así como "1 Space Company", "2 Spa Resort", etc., con un número seguido de palabras. Y necesitabas el comodín delante de tu clave de búsqueda para pasar la parte del número. (Esto es para aclarar mi primer comentario.) ¿Estoy adivinando correctamente o no?

+0

¿qué quieres decir? –

+0

¿Un valor de campo para "1 compañía espacial"? ¿Por qué estos dos campos no son "1" y "Compañía espacial"? Es imposible crear un índice solo en la parte del nombre, y aparentemente es realmente dos elementos de datos diferentes, o no estaría preguntando sobre la clasificación en un campo parcial. – dkretz

+0

Un gran problema es su "LIKE '% spa%'". Cualquier tecla "LIKE" que comience con un comodín es un escaneo automático de tabla. – dkretz

1

Yendo del ejemplo superior, al menos en MSSQL2005 cambiar el CLUSTERED a NO CLASIFICADO hará que realice una exploración de tabla. CLUSTERED te da una búsqueda de índice. Parece que coincide con las condiciones de la pregunta.

 
CREATE TABLE tblTest(ID INT, colname VARCHAR(20)) 
CREATE CLUSTERED INDEX tstidx1_tblTest ON tblTest(colname); 
INSERT tblTest SELECT 1,'Space Company' 
INSERT tblTest SELECT 2,'Spa Resort' 
INSERT tblTest SELECT 3,'Spa Hotel' 
INSERT tblTest SELECT 4,'Spare Parts' 
INSERT tblTest SELECT 5,'WithoutTheKeyword' 

SELECT * FROM tblTest WHERE colname LIKE 'Spa%' 
ORDER BY DIFFERENCE(colname,'Spa') DESC; 

DROP TABLE tblTest 
1

Básicamente necesita definir (precisamente) cuál es realmente su función de clasificación. ¿Qué pasa si tienes una fila que es "The Spa"? o "spa.com"? Una vez que tiene eso definido, necesita poner esa lógica en su cláusula ORDER BY.Por ejemplo:

SELECT 
    name 
FROM 
    Some_Table 
WHERE 
    name LIKE '%spa%' 
ORDER BY 
    CASE 
     WHEN name LIKE '% ' + @search_word + ' %' THEN 1 -- Notice the spaces 
     ELSE 2 
    END, 
    name 

Como alternativa, puede escribir una función de clasificación y el uso que:

SELECT 
    name 
FROM 
    Some_Table 
WHERE 
    name LIKE '%' + @search_word + '%' 
ORDER BY 
    dbo.GetNameMatchRank(name, @search_word) 

rendimiento en grandes conjuntos de resultados no puede ser demasiado grande, por lo que este enfoque depende de su resultado de la búsqueda se esperaba tamaños.

Cuestiones relacionadas