2012-03-27 9 views
5

domanda semplice:SQL - Dove criteri per trovare i nomi tra AF

Ho bisogno di una soluzione in modo che posso trovare, diciamo i nomi, tra AF, compresi tutti i nomi che iniziano con F.

Se usa BETWEEN o A> = value < = F scopri che si ferma a F. Quindi sto postando questo per i suggerimenti.

NOTA: L'utente vedrà 2 caselle di testo che accettano un intervallo che l'utente può digitare. L'utente raffina quanto lontano nel confine F in quanto tale: i tipi di utente in "Fa" significa che il risultato dovrebbe restituire: Fauder, Fail, Famber, ecc.

Attualmente ho 2 soluzioni ma c'è un un modo migliore.

Soluzione 1: Questo aggiungerà 1 al limite esterno ma potrebbe includere risultato se c'è un nome che è singolo 'G', tuttavia altamente improbabile. WHERE name> = 'A' e < = CHAR (ASCII ('F') + 1)

Soluzione 2: Questa soluzione accoda ultima lettera di volte la lunghezza campo alfabeto. WHERE name> = 'A' e < = 'FZZZZZZZZZZZZZZZZZZZZZ'

Anche se le soluzioni di cui sopra sono realizzabili, la mia ricerca può essere raffinato in quanto tali: A alla Fs (dovrebbe darmi tutto dalla A alla compreso Fs .. ..). Con questa soluzione # 1 è rotto poiché funziona con singolo ASCII.

suggerimenti sono i benvenuti.

+0

per quale server? –

+0

SQL Server 2000 o successivo – ActiveX

risposta

1

In un commento è estendere l'obbligo di includere A-Fxxx.

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

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

Si noti che questo non include funzioni sul campo name; tali funzioni impediscono la ricerca di intervalli sugli indici. Tuttavia, l'inclusione dello OR degrada anche nell'indice. Anche se è codice extra, questo in realtà può essere più performante è certi casi ...

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

UNION ALL 

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


EDIT

Col senno di poi, il vostro Soluzione 2, anche se non lo fai mi piace, è probabilmente il migliore.

svolta Fxxx-FxxxZZZZZZZZZZ è abbastanza semplice, con STUFF(), a condizione che si conosce la lunghezza della stringa massima, che si dovrebbe fare come il database è tuo.

Non ha alcuna funzione nel campo name e non utilizza uno OR nella clausola WHERE. Il che significa che ottieni una ricerca di raggio puro su qualsiasi indice.

Per quanto riguarda le prestazioni, non penso che si possa migliorare su questo.

+0

Questo è esattamente quello che stavo cercando! Grazie mille e grazie a tutti per le risposte. – ActiveX

9

Si può fare:

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

Solo se potessimo scrivere codice. Sto cercando una formula. Quanto sopra restituirà anche un nome che è 'G' che non è corretto. – ActiveX

+2

@ActiveX - Cosa intendi con "una formula" ?, quali sono i parametri previsti per la tua query ?, e no, non restituirà un nome che è 'G'. – Lamak

+0

@ActiveX: utilizza '<' piuttosto che '<=' o 'BETWEEN'. È un pattern molto normale e potente, a cui non importa quanti caratteri ci sono nel campo 'name', o richiedono qualche funzione sul campo' name' (che è importante in quanto tali funzioni distruggono la capacità di usare un intervallo di indice cercare). Personalmente, questo è esattamente quello che userei. – MatBailie

4

ne dici di questo?

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

Non male. Funzionerà ma richiede più programmazione. Nel mio caso l'utente può perfezionare la ricerca in: A - Fs, o A Fxxx. Potrei usare il tuo approccio e scrivere del codice per calcolare la lunghezza del campo del secondo limite e alimentarlo al substr ma sta diventando complicato. – ActiveX

+2

Funziona, ma inserendo una funzione attorno al campo 'name' si impedisce la ricerca di indici e si ottiene una scansione completa. – MatBailie

+1

@ActiveX - Cosa intendi con l'uso in grado di specificare 'A' -' Fxxx'? Questo cambia in modo significativo il comportamento che hai descritto nella tua domanda. Si prega di aggiornare la domanda per includere tutte le funzionalità necessarie? – MatBailie

2

sarà questo lavoro per voi:

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

Funziona, ma inserendo una funzione attorno al campo 'name' si impedisce la ricerca di indici e si ottiene una scansione completa. – MatBailie

2

Quanto più semplice è possibile farlo?

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

Funzionerà solo con il valore di un singolo carattere. Non con gamme come: A-Fa, A-Fb. Non ero esplicito sulla mia domanda, mi scuso. Ho modificato la mia domanda e aggiunto ulteriori dettagli. – ActiveX

Problemi correlati