Klauzule SELECT i FROM to dwie najważniejsze klauzule pojawiające się w prawie każdym zapytaniu pobierającym dane.

Klauzula FROM

Wracając do przetwarzania logicznego zapytania, klauzula FROM jest pierwszą rozpatrywaną logicznie klauzulą w zapytaniu SELECT. Pełni ona dwie zasadnicze role:

  • Jest to klauzula w której wyliczamy tabele które chcemy użyć w zapytaniu.
  • Jest to klauzula w której używamy operatorów na tabelach jak np. JOIN.

W tej lekcji skupimy się na pierwszej roli. Druga rola zostanie szerzej omówiona w kolejnych lekcjach. Jako prosty przykład z bazy danych TSQL2012, użyjemy następującego zapytania używającego klauzuli FROM do określenia tabeli HR>Employees która będzie użyta w zapytaniu:

USE [TSQL2012]
GO
SELECT empid, firstname, lastname
FROM HR.Employees;

Należy zwrócić uwagę na dwu częściową nazwę odwołania do tabeli. Pierwsza część HR to schemat a druga Employees to nazwa tabeli. W niektórych przypadkach T-SQL pozwala na ominięcie nazwy schematu, stosowany jest wtedy niejawny proces dopasowania schematu. Dobrą praktyką jest stosowanie nazw schematów zawsze. Pozwala to uniknąć sytuacji w której serwer dopasuje inny schemat do tabeli niż byśmy chcieli oraz zmniejsza koszt wykonania zapytania który wówczas jest powiększony o znalezienie odpowiedniego schematu. W klauzuli FROM można nadać alias tabeli którą wybraliśmy. Można do tego użyć dwóch form nadania aliasu, oto one:

  • <TABLE> <alias> np. HR.Employees E
  • <TABLE> AS <alias>  np. HR.Employees AS E

Gdy używamy aliasów to konwencja jest taka aby nadawać im krótkie nazwy, typowym przypadkiem jest pierwsza litera nazwy tabeli jak E dla Employees. Nadanie aliasu tabeli powoduje zmianę nazwy po której się do niej odwołujemy w aktualnym zapytaniu. Oryginalna nazwa tabeli nie jest już rozpoznawana.

Klauzula SELECT

Klauzula SELECT ma dwie główne role:

  • Wylicza wyrażenia wynikowe kwerendy, ewentualnie przypisuje im aliasy jeżeli istnieje taka potrzeba.
  • Eliminuje duplikaty z użyciem klauzuli DISTINCT.

Przykład dla pierwszej roli:

USE [TSQL2012]
GO
SELECT empid, firstname, lastname
FROM HR.Employees;

W klauzuli FROM wybieramy tabelę HR.Employees jako tabelę wejściową zapytania. Klauzula SELECT wylicza trzy atrybuty z tabeli które mają być zwrócone na wyjściu zapytania. T-SQL pozwala na użycie gwiazdki (*) jako alternatywy dla wypisania listy wszystkich atrybutów z tabel wejściowych lecz jest to zła praktyka z wielu powodów. Najczęściej potrzebujemy zwrócić tylko kilka atrybutów a użycie * jest leniwym sposobem, który może spowodować, że SQL Serwer nie będzie mógł zoptymalizować tak samo zapytania. Ponadto więcej danych jest przesyłanych przez sieć co ma negatywny wpływ na wydajność systemu i sieci. Dodatkowo tabela może zostać zmieniona po jakimś czasie i użycie * zamiast listy atrybutów może zwracać inną listę atrybutów niż wcześniej. Klauzula SELECT pozwala na nadanie aliasów wyrażeniom które są zdefiniowane jako wyniki. Można nadać alias na kilka sposobów, oto one:

  • <expression> AS <alias> np. empid AS EmployeeId
  • <expression> <alias> np. empid EmployeeId
  • <alias> = <expression> np. EmployeeId = empid

Preferowana metodą jest ta z użyciem klauzuli AS ponieważ jest standardem i jest najbardziej czytelna. Druga metoda jest mniej czytelna i sprawia, że trudno dostrzec pewien błąd w kodzie. Rozważmy poniższe zapytanie:

SELECT empid, firstname lastname
FROM HR.Employees;

W porównaniu do poprzedniego zapytania brakuje tylko przecinka między kolumnami. Zapytanie nie zwróci błędu lecz nada alias lastname dla kolumny firstname. Nadawanie aliasów atrybutom klauzuli SELECT ma dwa główne powody używania. Pierwszym jest konieczność nadania innej nazwy zwracanemu atrybutowi jak na przykład zastąpienie atrybutu empid aliasem EmployeeId:

SELECT empid AS EmployeeId, firstname, lastname
FROM HR.Employees;

Drugim powodem używania jest nazwanie wyrażeń które są nienazwane. Jako przykład można wygenerować atrybut który złączy atrybuty firstname i lastname jak w zapytaniu:

SELECT empid, firstname + N' ' + lastname
FROM HR.Employees;

empid ----------- ------------------------------- 1 Sara Davis 2 Don Funk 3 Judy Lew ... Wynik tego zapytania jest nierelacyjny ponieważ nie wszystkie zwracane atrybuty nie mają nazwy. Nadając alias wyrażeniu sprawiamy, że zapytanie jest relacyjne:

SELECT empid, firstname + N' ' + lastname AS fullname
FROM HR.Employees;

empid fullname ----------- ------------------------------- 1 Sara Davis 2 Don Funk 3 Judy Lew ... Ponieważ T-SQL domyślnie nie eliminuje duplikatów to ich wystąpienie jest możliwe. Wynik z duplikatami jest rozważany jako nierelacyjny. Dlatego można eliminować duplikaty za pomocą klauzuli DISTINCT jak na przykładzie poniżej:

SELECT DISTINCT country, region, city
FROM HR.Employees;

country region city --------------- --------------- --------------- UK NULL London USA WA Kirkland USA WA Redmond USA WA Seattle USA WA Tacoma Pomiędzy standardem SQL i T-SQL istnieje różnica w minimalnych wymaganiach zapytań. W standardzie SQL zapytanie musi mieć przynajmniej klauzule SELECT i FROM. T-SQL dopuszcza zapytania które posiadają tylko klauzulę SELECT. Są to zapytania które zwracają tylko jeden wiersz np:

SELECT 10 AS col1, 'ABC' AS col2;

col1 col2 ----------- ---- 10 ABC

Delimiters - identyfikatory rozgraniczające

Gdy odwołujemy się do identyfikatorów atrybutów, schematów, tabeli i innych obiektów to istnieją przypadki kiedy musimy zastosować ograniczniki tych identyfikatorów. T-SQL pozwala na użycie dwóch rodzajów ograniczników

  • standard SQL - "<identyfikator>"  np. "Sales"."Orders"
  • [<identyfikator>] np. [Sales].[Orders]

Gdy identyfikator jest "regularny" to ograniczniki są opcjonalne. Regularny oznacza, że spełnia pewne reguły formatowania:

  • Pierwszym znakiem musi być litera z zakresu od A do Z, podkreślnik "_", małpa "@" lub "#".
  • Kolejne znaki mogą być literami, numerami, znakami "@, _, $, #"
  • Identyfikator nie może być słowem kluczowym T-SQL.
  • Identyfikator nie może mieć spacji i znaków uzupełniających.

Identyfikator który nie spełnia którejś z wymienionych zasad musi być objęty ogranicznikami. Np atrybut 2006 nie jest regularny ponieważ zaczyna się od cyfry, więc musi być zapisany jako "2006" lub [2006].

Ćwiczenia

I. Użycie aliasów w prostych zapytaniach

  1. Napisz zapytanie zwracające shipperid, companyname i phone z tabeli Sales.Shippers.
    USE TSQL2012;
    SELECT shipperid, companyname, phone
    FROM Sales.Shippers;
    
    shipperid companyname phone ---------- -------------- --------------- 1 Shipper GVSUA (503) 555-0137 2 Shipper ETYNR (425) 555-0136 3 Shipper ZHISN (415) 555-0138
  2. Napisz zapytanie używające aliasu nazwy tabeli które zwraca shipperid, companyname i phone z aliasem phoe number z tabeli Sales.Shippers.
    SELECT S.shipperid, companyname, phone AS [phone number]
    FROM Sales.Shippers AS S;
    
    shipperid companyname phone number ----------- ---------------------------------------- ------------------------ 1 Shipper GVSUA (503) 555-0137 2 Shipper ETYNR (425) 555-0136 3 Shipper ZHISN (415) 555-0138

Podsumowanie

  1. Klauzula FROM jest pierwszą wykonywaną klauzulą w logicznej kolejności zapytania. identyfikuje ona tabele z których chcemy pobrać dane oraz operatory połączenia między tymi tabelami. Można używać aliasów dla tabel w klauzuli FROM.
  2. Klauzula SELECT służy do określenia wyrażeń które chcemy zdefiniować jako atrybuty zwracane zapytania. Można nadać aliasy do zwracanych atrybutów. W klauzuli SELECT możemy również wymusić usunięcie duplikatów z wyniku za pomocą klauzuli DISTINCT.