Sprawdzanie instrukcji SELECT

Ukończone

Język Transact-SQL lub T-SQL to dialekt standardowego języka SQL ANSI używanego przez produkty i usługi Microsoft SQL. Jest on podobny do standardowego języka SQL. Większość z naszych skupień koncentruje się na instrukcji SELECT, która ma zdecydowanie najwięcej opcji i odmian dowolnej instrukcji DML.

Zacznijmy od zapoznania się z ogólnym sposobem przetwarzania instrukcji SELECT. Kolejność zapisywania instrukcji SELECT nie jest kolejnością oceniania i przetwarzania przez aparat bazy danych programu SQL Server.

Rozważ następujące zapytanie:

SELECT OrderDate, COUNT(OrderID) AS Orders
FROM Sales.SalesOrder
WHERE Status = 'Shipped'
GROUP BY OrderDate
HAVING COUNT(OrderID) > 1
ORDER BY OrderDate DESC;

Zapytanie składa się z instrukcji SELECT, która składa się z wielu klauzul, z których każda definiuje określoną operację, która musi być stosowana do pobieranych danych. Zanim zbadamy kolejność operacji w czasie wykonywania, pokrótce przyjrzyjmy się temu, co robi to zapytanie, chociaż szczegóły różnych klauzul nie zostaną omówione w tym module.

Klauzula SELECT zwraca kolumnę OrderDate i liczbę wartości OrderID, do których jest przypisywana nazwa (lub alias) Orders:

SELECT OrderDate, COUNT(OrderID) AS Orders

Klauzula FROM określa, która tabela jest źródłem wierszy zapytania; w tym przypadku jest to tabela Sales.SalesOrder :

FROM Sales.SalesOrder

Klauzula WHERE filtruje wiersze z wyników, zachowując tylko te wiersze, które spełniają określony warunek; w tym przypadku zamówienia o stanie "wysłane":

WHERE Status = 'Shipped'

Klauzula GROUP BY przyjmuje wiersze spełniające warunek filtru i grupuje je według kolumny OrderDate, aby wszystkie wiersze z tą samą wartością OrderDate były traktowane jako pojedyncza grupa, a jeden wiersz zostanie zwrócony dla każdej grupy:

GROUP BY OrderDate

Po utworzeniu grup klauzula HAVING filtruje grupy na podstawie własnego predykatu. W wynikach zostaną uwzględnione tylko daty z więcej niż jedną kolejnością:

HAVING COUNT(OrderID) > 1

Na potrzeby podglądu tego zapytania końcowa klauzula to ORDER BY, która sortuje dane wyjściowe w kolejności malejącej OrderDate:

ORDER BY OrderDate DESC;

Teraz, gdy już wiesz, co robi każda klauzula, przyjrzyjmy się kolejności, w jakiej program SQL Server rzeczywiście je ocenia:

  1. Klauzula FROM jest najpierw obliczana, aby podać wiersze źródłowe pozostałej części instrukcji. Tabela wirtualna jest tworzona i przekazywana do następnego kroku.
  2. Klauzula WHERE jest obok oceny, filtrując te wiersze z tabeli źródłowej, która jest zgodna z predykatem. Przefiltrowana tabela wirtualna jest przekazywana do następnego kroku.
  3. Funkcja GROUP BY jest następna, organizując wiersze w tabeli wirtualnej zgodnie z unikatowymi wartościami znajdującymi się na liście GROUP BY. Zostanie utworzona nowa tabela wirtualna zawierająca listę grup i przekazana do następnego kroku. Od tego momentu w przepływie operacji odwołania do innych elementów mogą odwoływać się tylko kolumny na liście GROUP BY lub funkcje agregujące.
  4. Klauzula HAVING jest oceniana w następnej kolejności, odfiltrując całe grupy na podstawie jej predykatu. Tabela wirtualna utworzona w kroku 3 jest filtrowana i przekazywana do następnego kroku.
  5. Klauzula SELECT na koniec zostanie wykonana, określając, które kolumny będą wyświetlane w wynikach zapytania. Ponieważ klauzula SELECT jest obliczana po innych krokach, nie można używać aliasów kolumn (w naszym przykładzie Orders) w klauzuli GROUP BY ani HAVING.
  6. Klauzula ORDER BY jest ostatnią do wykonania, sortując wiersze określone na podstawie listy kolumn.

Aby zastosować tę wiedzę do naszego przykładowego zapytania, poniżej przedstawiono kolejność logiczną w czasie wykonywania powyższej instrukcji SELECT:

FROM Sales.SalesOrder
WHERE Status = 'Shipped'
GROUP BY OrderDate 
HAVING COUNT(OrderID) > 1
SELECT OrderDate, COUNT(OrderID) AS Orders
ORDER BY OrderDate DESC;

Nie wszystkie możliwe klauzule są wymagane w każdej instrukcji SELECT, którą piszesz. Jedyną wymaganą klauzulą jest klauzula SELECT, która może być używana samodzielnie w niektórych przypadkach. Zazwyczaj klauzula FROM jest również uwzględniana w celu zidentyfikowania tabeli, do których jest wykonywane zapytanie. Ponadto język Transact-SQL zawiera inne klauzule, które można dodać.

Jak już wiesz, nie piszesz zapytań T-SQL w tej samej kolejności, w której są one logicznie oceniane. Kolejność wykonywania oceny określa, jakie dane są dostępne dla tych klauzul, ponieważ klauzula ma dostęp tylko do informacji udostępnionych z już przetworzonej klauzuli. Z tego powodu ważne jest zrozumienie prawdziwej kolejności przetwarzania logicznego podczas pisania zapytań.

Wybieranie wszystkich kolumn

Klauzula SELECT jest często określana jako lista SELECT, ponieważ zawiera ona listę wartości, które mają zostać zwrócone w wynikach zapytania.

Najprostszą formą klauzuli SELECT jest użycie znaku gwiazdki (*) w celu zwrócenia wszystkich kolumn. W przypadku użycia w zapytaniach języka T-SQL jest ona nazywana gwiazdką. Chociaż funkcja SELECT * jest odpowiednia do szybkiego testu, należy unikać używania go w środowisku produkcyjnym z następujących powodów:

  • Zmiany w tabeli, które dodają lub rozmieszą kolumny, zostaną odzwierciedlone w wynikach zapytania, co może spowodować nieoczekiwane dane wyjściowe dla aplikacji lub raportów korzystających z zapytania.
  • Zwracanie danych, które nie są potrzebne, może spowolnić zapytania i spowodować problemy z wydajnością, jeśli tabela źródłowa zawiera dużą liczbę wierszy.

Na przykład poniższy przykład pobiera wszystkie kolumny z (hipotetycznej) tabeli Production.Product .

SELECT * FROM Production.Product;

Wynikiem tego zapytania jest zestaw wierszy zawierający wszystkie kolumny dla wszystkich wierszy tabeli, co może wyglądać mniej więcej tak:

ProductID

Nazwisko

ProductNum

Color

StandardCost (Koszt standardowy)

ListPrice

Rozmiar

Weight

ProductCatID

680

Rama szosowa HL — czarna, 58

FR-R92B-58

Black

1059.31

1431.5

58

1016.04

18

706

Rama szosowa HL — czerwona, 58

FR-R92R-58

Czerwony

1059.31

1431.5

58

1016.04

18

707

Kask Sport-100, czerwony

HL-U509-R

Czerwony

13.0863

34.99

35

708

Kask Sport-100, czarny

HL-U509

Black

13.0863

34.99

35

...

...

...

...

...

...

...

...

...

Wybieranie określonych kolumn

Jawna lista kolumn umożliwia kontrolowanie dokładnie, które kolumny są zwracane i w jakiej kolejności. Każda kolumna w wyniku będzie mieć nazwę kolumny jako nagłówek.

Rozważmy na przykład następujące zapytanie; ponownie używa hipotetycznej tabeli Production.Product .

SELECT ProductID, Name, ListPrice, StandardCost
‎FROM Production.Product;

Tym razem wyniki obejmują tylko określone kolumny:

ProductID

Nazwisko

ListPrice

StandardCost (Koszt standardowy)

680

Rama szosowa HL — czarna, 58

1431.5

1059.31

706

Rama szosowa HL — czerwona, 58

1431.5

1059.31

707

Kask Sport-100, czerwony

34.99

13.0863

708

Kask Sport-100, czarny

34.99

13.0863

...

...

...

...

Wybieranie wyrażeń

Oprócz pobierania kolumn przechowywanych w określonej tabeli klauzula SELECT może wykonywać obliczenia i manipulacje, które używają operatorów do łączenia kolumn i wartości lub wielu kolumn. Wynikiem obliczeń lub manipulacji musi być jednowartościowy (skalarny) wynik, który będzie wyświetlany w wyniku jako oddzielna kolumna.

Na przykład następujące zapytanie zawiera dwa wyrażenia:

SELECT ProductID,
      Name + '(' + ProductNumber + ')',
  ListPrice - StandardCost
FROM Production.Product;

Wyniki tego zapytania mogą wyglądać mniej więcej tak:

ProductID

680

HL Road Frame -, 58(FR-R92B-58)

372.19

706

HL Road Frame - Czerwony, 58(FR-R92R-58)

372.19

707

Kask Sport-100, Czerwony(HL-U509-R)

21.9037

708

Kask Sport-100, (HL-U509)

21.9037

...

...

...

Istnieje kilka interesujących rzeczy do zanotowania następujących wyników:

  • Kolumny zwrócone przez dwa wyrażenia nie mają nazw kolumn. W zależności od narzędzia, którego używasz do przesyłania zapytania, brakująca nazwa kolumny może być wskazywana przez pusty nagłówek kolumny, literał "brak nazwy kolumny" lub domyślną nazwę, taką jak kolumna1. Zobaczymy, jak określić alias nazwy kolumny w zapytaniu w dalszej części tej sekcji.
  • Pierwsze wyrażenie używa + operatora do łączenia wartości ciągów (opartych na znakach), podczas gdy drugie wyrażenie używa - operatora do odejmowania jednej wartości liczbowej z innej. W przypadku użycia z wartościami + liczbowymi operator wykonuje dodawanie. Dlatego ważne jest, aby zrozumieć typy danych kolumn, które są uwzględniane w wyrażeniach. W następnej sekcji omówimy typy danych.

Określanie aliasów kolumn

Możesz określić alias dla każdej kolumny zwróconej przez zapytanie SELECT, alternatywnie dla nazwy kolumny źródłowej lub przypisać nazwę do danych wyjściowych wyrażenia.

Na przykład poniżej przedstawiono to samo zapytanie co poprzednio, ale z aliasami określonymi dla każdej z kolumn:

SELECT ProductID AS ID,
      Name + '(' + ProductNumber + ')' AS ProductName,
  ListPrice - StandardCost AS Markup
FROM Production.Product;

Wyniki tego zapytania obejmują określone nazwy kolumn:

ID

ProductName

Narzut

680

HL Road Frame -, 58(FR-R92B-58)

372.19

706

HL Road Frame - Czerwony, 58(FR-R92R-58)

372.19

707

Kask Sport-100, Czerwony(HL-U509-R)

21.9037

708

Kask Sport-100, (HL-U509)

21.9037

...

...

...

Uwaga

Słowo kluczowe AS jest opcjonalne podczas określania aliasu, ale dobrym rozwiązaniem jest uwzględnienie go w celu wyjaśnienia.

Formatowanie zapytań

Możesz zauważyć w przykładach w tej sekcji, że możesz elastycznie sformatować kod zapytania. Można na przykład napisać każdą klauzulę (lub całe zapytanie) w jednym wierszu lub podzielić ją na wiele wierszy. W większości systemów baz danych kod jest niewrażliwy na wielkość liter, a niektóre elementy języka T-SQL są opcjonalne (w tym słowo kluczowe AS, jak wspomniano wcześniej, a nawet średnik na końcu instrukcji).

Weź pod uwagę następujące wskazówki, aby kod T-SQL był łatwo czytelny (i w związku z tym łatwiej zrozumieć i debugować!):

  • Wielką literą słów kluczowych języka T-SQL, takich jak SELECT, FROM, AS itd. Wielkie litery słów kluczowych to powszechnie używana konwencja, która ułatwia znalezienie każdej klauzuli złożonej instrukcji.
  • Uruchom nowy wiersz dla każdej klauzuli głównej instrukcji.
  • Jeśli lista SELECT zawiera więcej niż kilka kolumn, wyrażeń lub aliasów, rozważ wyświetlenie każdej kolumny w osobnym wierszu.
  • Wcięcie wierszy zawierających podklasy lub kolumny, aby wyjaśnić, który kod należy do każdej klauzuli głównej.