11. Filtracja danych

11. Filtracja danych

Autor: Grzegorz Chuchra

Opublikowano: 3/8/2006, 12:00 AM

Liczba odsłon: 58089

Streszczenie

Artykuł ten chciałbym poświęcić klauzuli WHERE. Ponieważ do tej pory traktowaliśmy ją bardzo ogólnikowo, myślę, że przyszedł czas na dokładne przeanalizowanie możliwości, których może nam dostarczyć skuteczne jej wykorzystanie.

Treść

Klauzula WHERE służy do ograniczenia zbioru danych, na których przeprowadzana będzie operacja. Dotyczy to zarówno operacji SELECT, jak i UPDATE i DELETE. W warunkach wyszukiwania można uwzględnić szereg operatorów porównania, dopasowywania łańcuchów znaków i wartości niezdefiniowanej NULL. Sama składnia ograniczająca warunki wyszukiwania jest dość prosta:

WHERE warunki_wyszukiwania

Podstawowy sposób filtracji danych polega na pobieraniu wartości większy, mniejszy lub równy  i porównaniu z pewną wartością, którą podajemy. Przykładem może być wybranie kontaktu z osobami o imieniu Marcin lub ludzi urodzonych po roku 1980. Wszystkie te operacje można bez problemu wykonać za pomocą operatorów porównania. Poniższa tabela przedstawia operatory porównania dostępne w standardzie Transact-SQL.

=

Równy

Większy

Mniejszy

>=

Większy, równy

<=

Mniejszy, równy

<> 

Różny

Przejdźmy teraz do przeanalizowania prostego zapytania, które już wielokrotnie przetoczyło się przez ten kurs. Wygenerujmy sobie w Query Designer skrypt wylistowujący kontakty do osób mających nazwisko Diaz. Poprawnie wygenerowane zapytanie powinno wyglądać w następująco:

SELECT     Person.Contact.*
FROM       Person.Contact
WHERE      (LastName = N'Diaz')

Skupmy się jednak na klauzuli WHERE. Kolumna LastName jest typu znakowego, z tego względu tekst wpisany do designera jest standardowo konwertowany do łańcuch znakowy. W tym celu SQL Server zastosował funkcję konwersji:

 N' wartość_do_konwersji ’

Sprawdźmy, co się stanie, jeśli kolumna, po której będziemy wyszukiwać, będzie miała wartość integer (całkowitoliczbową).

SELECT   Person.Contact.*
FROM     Person.Contact
WHERE    (ContactID = 257)

Ponieważ kolumna ContactID jest typu całkowitego designer nie musi, a nawet nie może konwertować wartości. Próba wpisania w kolumnie Filter wyrażenia innego niż cyfra zakończy się niepowodzeniem i wypisaniem komunikatu o błędzie.
Wiemy już jak wybierać informacje o pojedynczym wierszu. Teraz przejdźmy do wybrania wszystkich rekordów z bazy, gdzie data modyfikacji wiersza jest większa niż 2004-07-26. W tym celu przy kolumnie związanej z nakładaniem warunków wpisujemy datę 2004-07-26.

SELECT    Person.Contact.*
FROM      Person.Contact
WHERE     (ModifiedDate > CONVERT(DATETIME, '2004-07-26 00:00:00', 102))

@STRONA@

Zapytanie, które dostaliśmy jako wynik naszego ograniczenia, jest dość skomplikowane. Spowodowane jest to tym, iż kolumna, na którą nakładamy warunki jest typu datetime. Podobnie jak w przypadku łańcucha znakowego, designer konwertuje tekst wpisany przez użytkownika do formatu takiego, jaki ma kolumna. Konwersja ta jest jednak znacznie bardziej skomplikowana i używam do niej systemowej funkcji CONVERT. Funkcja ta przyjmuje jako pierwszy argument typ na jaki konwertujemy. Drugim argumentem jest obiekt, którego typ chcemy zmienić, zaś ostatni parametr określa styl podawania daty. W zależności, czy rok oddzielimy od miesiąca myślnikami czy kropkami musimy podać stosowny do tego sposób kodowania. Tabelę określającą odpowiednie formaty zamieściłem poniżej.

Rok w postaci dwóch ostatnich cyfr (yy)

Rok w postaci czterocyfrowej (yyyy)

Nazwa standardu

Format daty

1

101

USA

MM/dd/yy

2

102

ANSI

yy.MM.dd

3

103

UK/Francuski

dd/MM/yy

4

104

Niemiecki

dd.MM.yy

5

105

Włoski

dd-MM-yy

6

106

Brak

dd MM yy

7

107

Brak

MM dd, yy

10

110

USA

MM-dd-yy

11

111

Japoński

yy/MM/dd

Wiemy już, jak przeszukiwać tabelę po typie całkowitym, znakowym oraz po dacie. Spróbujmy teraz złożyć wszystko to razem i zapisać zapytanie wybierające wszystkie kontakty, które zostały zmodyfikowane po 21 lipca 2004 dla osób z nazwiskiem Diaz lub tą, która ma identyfikator równy 13365. Takiego zapytania jeszcze nie pisaliśmy. Mamy tu do czynienia z dwoma różnymi operatorami logicznymi pomiędzy poszczególnymi warunkami AND, OR. Pierwszą operacją jest wybranie z tabeli pól, jakie będą nam potrzebne, czyli LastName, ModificationDate i ContactID. Jeśli mamy już wybrane pola przechodzimy do określania warunków. Zacznijmy od wyznaczenia zbioru rekordów, które zostały zmodyfikowane po 2004-07-21. Czyli w kolumnie Filter wpisujemy naszą datę poprzedzoną znakiem >. Teraz dokładamy warunek ograniczający zbiór rekordów do osób z nazwiskiem Diaz. Na tą chwilę zapytanie wygląda następująco:

SELECT    Person.Contact.*
FROM      Person.Contact
WHERE     (ModifiedDate > CONVERT(DATETIME, '2004-07- 21 00:00:00', 102)) AND (LastName = N'Diaz')

Teraz musimy dodać warunek, który dołoży do naszego zbioru rozwiązań kontakt z identyfikatorem 13365. W tym celu do klauzuli WHERE dodajemy:

OR (ContactID = 13365)

Całe zapytanie wygląda tak:

SELECT    LastName, ModifiedDate, ContactID
FROM      Person.Contact
WHERE     (ModifiedDate > CONVERT(DATETIME, '2004-07-21 00:00:00', 102)) AND (LastName = N'Diaz') OR (ContactID = 13365)

Jednak przeważnie podczas wyszukiwania nie znamy całego nazwiska lub imienia (albo po prostu nie chce nam się całego wpisywać) wtedy musimy nieco zmodyfikować nasze zapytanie. Jeśli chcielibyśmy wyświetlić listę osób, których imię zaczyna się na literę A zaś nazwisko na S powinniśmy użyć słowo kluczowe LIKE. Składnia wyrażenia jest następująca:

WHERE nazwa_kolumny [NOT] LIKE ‘szukane_tekst’

a zapytanie wygląda w następujący sposób:

SELECT    FirstName, LastName
FROM      Person.Contact
WHERE     (FirstName LIKE N'A%') AND (LastName LIKE N'S%')

Znak % jest znakiem autouzupełnienia. Mówi o tym, że po naszej literze może występować dowolny ciąg różnych znaków. Gdybyśmy przed literą A dodali znak % oznaczałoby to, że szukamy takich imion, które posiadają literę A nie zważając na pozycję na której ona występuje. Lista innych znaków autouzupełnienia przedstawia poniższa tabela.

%

Zero lub więcej znaków

_

Pojedynczy znak

[]

Znak z podanego zakresu

[^]

Znak który nie należy do podanego zakresu

Jeśli chcielibyśmy znaleźć osobę, której nazwisko zaczyna się na literę D, po niej występują dwie inne litery, następnie litera Z i ciąg innych liter musielibyśmy uruchomić następujący skrypt.

SELECT    FirstName, LastName
FROM      Person.Contact
WHERE     (LastName LIKE N'D__Z%')

Podsumowanie

W powyższym artykule dowiedzieliśmy się, jak w sposób efektywny ograniczać zbiór danych wynikowych ze względu na nasze potrzeby. Wszystkie skrypty, które utworzyliśmy były przedstawione na podstawie operacji SELECT jednak można bez żadnych przeszkód użyć ich zarówno w operacjach UPDATE jak i DELETE. Składnia klauzuli WHERE jest we wszystkich przypadkach taka sama.

Jak wykorzystać Copilot w codziennej pracy? Kurs w przedsprzedaży
Jak wykorzystać Copilot w codziennej pracy? Kurs w przedsprzedaży

Wydarzenia