2012-03-27 7 views
5

simple pregunta:SQL - Cuando los criterios para encontrar nombres entre AF

Necesito una solución para que pueda encontrar, digamos nombres, entre AF, incluyendo todos los nombres que comienzan con F.

Si use BETWEEN o A> = valor < = F descubre que se detiene en F. Entonces, estoy publicando esto para sugerencias.

NOTA: El usuario verá 2 cuadros de texto que aceptan un rango que el usuario puede escribir. El usuario refina qué tan lejos entrar en el límite F como tal: El usuario escribe 'Fa' significa que el resultado debe regresar: Fauder, Fail, Famber, ... etc

Actualmente tengo 2 soluciones, pero hay una una mejor manera.

Solución 1: Esto agregará 1 al límite exterior, pero puede incluir el resultado si hay un nombre que es solo 'G', aunque es poco probable. WHERE nombre> = 'A' y < = CHAR (ASCII ('F') + 1)

Solución 2: Esta solución añade última letra del alfabeto tiempos de longitud de campo. WHERE nombre> = 'A' y '= < FZZZZZZZZZZZZZZZZZZZZZ'

Aunque las soluciones anteriores son viables, mi búsqueda se pueden refinar tales como: A a Fs (me diera todo, desde la A a la e incluyendo Fs .. ..). Con esta solución, el n. ° 1 se rompe, ya que funciona con ascii único.

Sugerencias son bienvenidas.

+0

¿para qué servidor? –

+0

SQL Server 2000 o posterior – ActiveX

Respuesta

1

En un comentario que ampliar el requisito de incluir A-Fxxx.

SET @start = 'A' 
SET @end = 'Fxxx' 

SELECT 
    * 
FROM 
    table 
WHERE 
    (name >= @start AND name < @end) 
    OR (name LIKE @end + '%') 

Tenga en cuenta que esto no incluye funciones en el campo name; tales funciones evitan que el rango busque índices. Sin embargo, la inclusión del OR degrada la búsqueda del índice también. Aunque se trata de código extra, en realidad esto puede ser más performante es algunos casos ...

SELECT 
    * 
FROM 
    table 
WHERE 
    (name >= @start AND name < @end) 

UNION ALL 

SELECT 
    * 
FROM 
    table 
WHERE 
    (name LIKE @end + '%') 


EDITAR

En retrospectiva, su Solución 2, aunque no lo hace me gusta, es probablemente el mejor.

Convertir Fxxx en FxxxZZZZZZZZZZ es lo suficientemente simple con STUFF(), siempre que conozca la longitud máxima de la cadena, lo que debe hacer ya que la base de datos es suya.

que no tiene ninguna función en el campo name, y no utiliza un OR en la cláusula WHERE. Lo que significa que obtienes una búsqueda de rango puro en cualquier índice.

En cuanto a rendimiento, no creo que pueda mejorar esto.

+0

¡Eso es exactamente lo que estaba buscando! Muchas gracias y gracias a todos por las respuestas. – ActiveX

9

Usted puede hacer:

WHERE name >= 'A' AND name < 'G' 
+0

Solo si pudiéramos codificar cosas. Estoy buscando una fórmula. Lo anterior también devolverá un nombre que es 'G' que es incorrecto. – ActiveX

+2

@ActiveX - ¿Qué quiere decir con "una fórmula" ?, ¿cuáles son los parámetros esperados para su consulta ?, y no, no devolverá un nombre que sea 'G'. – Lamak

+0

@ActiveX - Esto usa '<' en lugar de '<=' o 'BETWEEN'. Es un patrón muy normal y poderoso, que no importa cuántos caracteres hay en el campo 'name', o requiere funciones en el campo' name' (que es importante ya que estas funciones destruyen la capacidad de usar un rango de índice). buscar). Personalmente, esto es exactamente lo que usaría. – MatBailie

4

¿Qué tal esto?

WHERE SUBSTR(name, 1, 1) >= 'A' AND SUBSTR(name, 1, 1) <= 'F' 
+0

No está mal. Eso funcionará, pero requiere más programación. En mi caso, el usuario puede refinar la búsqueda a: A - Fs, o A Fxxx. Podría utilizar su enfoque y escribir algún código para calcular la longitud del campo del segundo límite y alimentarlo al substr pero se está volviendo desordenado. – ActiveX

+2

Funciona, pero poner una función alrededor del campo 'name' impide búsquedas de índices y da como resultado un análisis completo. – MatBailie

+1

@ActiveX - ¿Qué quiere decir que el uso puede especificar 'A' -' Fxxx'? Eso cambia significativamente el comportamiento que describiste en tu pregunta. ¿Podría actualizar la pregunta para incluir todas las funciones que necesita? – MatBailie

2

es que esto funciona para usted:

select * 
from MyTable 
where left(name, 1) between 'a' and 'f' 
+1

Funciona, pero al poner una función alrededor del campo 'name' impide búsquedas de índice, y da como resultado un escaneo completo. – MatBailie

2

¿Cuánto más simple puede hacerlo?

WHERE NAME LIKE '[a-f]%' 
+0

Funcionará solo con el valor de un solo carácter. No con rangos tales como: A-Fa, A-Fb. No fui explícito en mi pregunta, me disculpo. He editado mi pregunta y he agregado más detalles. – ActiveX

Cuestiones relacionadas