2012-03-27 21 views
5

proste pytanie:SQL - Gdzie kryteriów wyszukiwania nazwy pomiędzy AF

muszę rozwiązanie tak, że mogę znaleźć, powiedzmy, nazwiska, między AF, w tym wszystkie nazwy, które zaczynają się od F.

Jeśli użyj BETWEEN lub A> = value < = F dowiadujesz się, że zatrzymuje się w F. Więc zamieszczam to dla sugestii.

UWAGA: Użytkownik zobaczy 2 pola tekstowe, które akceptują zakres, który użytkownik może wpisać. Użytkownik precyzuje, jak daleko należy przejść w granicach F jako taki: Typy użytkowników w "Fa" oznaczają, że wynik powinien powrócić: Fauder, Fail, Famber, ... itd.

Mam obecnie 2 rozwiązania, ale musi być lepszy sposób.

Rozwiązanie 1: Spowoduje to dodanie 1 do zewnętrznej granicy, ale może zawierać wynik, jeśli istnieje nazwa, która jest pojedynczym "G", co jest bardzo mało prawdopodobne. WHERE name> = 'a' i < = CHAR (ASCII ('F') + 1)

Rozwiązanie 2: Rozwiązanie dołącza ostatnią literę alfabetu razy długość pola. WHERE name> = „a” i „FZZZZZZZZZZZZZZZZZZZZZ < =”

Chociaż powyższe rozwiązania są wykonalne, moje poszukiwania mogą być rafinowane, takie jak: A do Fs (powinien dać mi wszystko od A do i włącznie Fs .. ..). Z tym rozwiązaniem 1 jest zepsuty, ponieważ działa z pojedynczym ASCII.

Propozycje są mile widziane.

+0

za jaki serwer? –

+0

SQL Server 2000 lub nowszy – ActiveX

Odpowiedz

1

w komentarzu rozszerzyć wymóg obejmują A - Fxxx.

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

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

Należy zauważyć, że nie obejmuje to funkcji w polu name; takie funkcje zapobiegają zasięgowi indeksów. Jednak włączenie parametru OR powoduje również pogorszenie indeksowania. Mimo że jest to dodatkowy kod, to rzeczywiście może być bardziej wydajnych jest kilka przypadków ...

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

UNION ALL 

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


EDIT

Z perspektywy czasu, Twój Rozwiązanie 2, chociaż nie lubić to, jest prawdopodobnie najlepszy.

Przekształcenie Fxxx na FxxxZZZZZZZZZZ jest wystarczająco proste z STUFF(), pod warunkiem, że znasz maksymalną długość ciągu znaków, którą powinieneś zrobić, ponieważ baza danych jest twoja.

Nie ma żadnych funkcji w polu name i nie korzysta z klauzuli OR w klauzuli WHERE. Co oznacza, że ​​uzyskujesz czysty zasięg dla dowolnego indeksu.

Wydajność, nie sądzę, że można poprawić w tej kwestii.

+0

Tego właśnie szukałem! Dziękuję bardzo i dziękuję wszystkim za odpowiedzi. – ActiveX

9

można zrobić:

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

Tylko jeśli moglibyśmy mocno kodować rzeczy. Szukam formuły. Powyższe zwróci również nazwę, która jest "G", która jest niepoprawna. – ActiveX

+2

@ActiveX - Co masz na myśli mówiąc "formuła"? Jakie parametry są oczekiwane dla zapytania ?, i nie, nie zwróci nazwy o nazwie "G". – Lamak

+0

@ActiveX - Używa '' 'zamiast' <= 'lub' BETWEEN'. Jest to bardzo normalny i potężny wzór, który nie dba o to, ile znaków znajduje się w polu "nazwa", lub wymaga jakichkolwiek funkcji w polu "nazwa" (co jest ważne, ponieważ takie funkcje niwelują możliwość korzystania z zakresu indeksów szukać). Osobiście to dokładnie to, czego bym użył. – MatBailie

4

Jak ten temat?

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

Nieźle. To zadziała, ale wymaga więcej programowania. W moim przypadku użytkownik może zawęzić wyszukiwanie do: A - Fs lub A Fxxx. Mógłbym użyć twojego podejścia i napisać jakiś kod, żeby obliczyć długość pola drugiej granicy i posłać ją do substr, ale staje się niechlujny. – ActiveX

+2

Działa, ale umieszczenie funkcji w polu 'name' zapobiega wyszukiwaniu indeksu i powoduje pełne skanowanie. – MatBailie

+1

@ActiveX - Co masz na myśli mówiąc o konkretnym użyciu 'A' -' Fxxx'? To znacznie zmienia zachowanie opisane w pytaniu. Czy mógłbyś zaktualizować pytanie tak, aby zawierał wszystkie wymagane funkcje? – MatBailie

2

Będzie to praca dla Ciebie:

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

Działa, ale umieszczenie funkcji w polu 'name' zapobiega wyszukiwaniu indeksu i powoduje pełne skanowanie. – MatBailie

2

O ile łatwiej można to zrobić?

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

Działa tylko z wartością pojedynczego znaku. Nie w zakresach takich jak: A-Fa, A-Fb. Nie było jednoznaczne na moje pytanie, przepraszam. Zmieniłem moje pytanie i dodałem więcej szczegółów. – ActiveX