Wykład piąty zawiera omówienie zagadnienie odczytywania danych z więcej niż jednej tabeli. Omówione zostanie zarówno odczytywanie danych z relacji utworzonych na kilku tabelach, jak też tworzenia wyników poprzez uzycie operatorów algebraicznych UNION, INTERSECT, EXCEPT.
Dotychczas wszystkie operacje wykonywane na danych dotyczyły zawsze tylko jednej tabeli. Odczytywaliśmy dane ze wszystkich, albo tylko z wybranych kolumn, z wszystkich wierszy, albo tylko z tych, dla których warunek zdefiniowany w klauzuli WHERE przyjmował wartość TRUE. Jednak, znając podstawy relacyjnego modelu danych wiemy, że będą one zapisywane w wielu tabelach, połączonych ze sobą związkami. Związki, które możemy zdefiniować i opisać werbalnie na poziomie koncepcyjnym, na poziomie logicznym realizowane są poprzez układ klucz główny – klucz obcy, czyli swego rodzaju wskaźniki. Poprzez porównanie wartości klucza głównego w tabeli nadrzędnej i wartości odpowiadającego mu klucza obcego w tabeli podrzędnej, możemy zidentyfikować powiązania pomiędzy rekordami. Każda znacząca, (czyli nie NULL) wartość klucza obcego w tabeli podrzędnej, wskazuje na dokładnie jeden rekord w tabeli nadrzędnej. I odwrotnie – każda wartość klucza głównego w tabeli nadrzędnej może wskazywać na jeden lub więcej rekordów w tabeli nadrzędnej. Identyfikacja tych powiązań sprowadza się do odszukania jednakowych wartości par {klucz główny, klucz obcy}.
Tyle teoria, spróbujmy obecnie przełożyć to na język SQL. Zaczniemy od pewnego eksperymentu. W celu poznania nazw i lokalizacji departamentów, w których zatrudnieni są poszczególni pracownicy, odczytajmy wynik polecenia
SELECT Ename, Dname, Loc FROM EMP, DEPT;
I tutaj spotyka nas pewne zaskoczenie. W tabeli EMP jest 14 rekordów, w tabeli DEPT 4, a wynik powyższego polecenia zawiera 56 rekordów. Przyjrzyjmy się im dokładnie. Wynika z nich, że nazwisko każdego pracownika pojawia się czterokrotnie – w połączeniu z nazwą i lokalizacją każdego departamentu. Z kolei każdy departament jest wyświetlany w połączeniu z nazwiskami wszystkich pracowników. Mamy to do czynienia z iloczynem kartezjańskim określonym na zbiorach wierszy z tabel EMP i DEPT.
Czy ten wynik, jako całość, jest prawdziwy? Raczej nie! Czy zawiera w sobie prawdziwe informacje? Oczywiście, że tak. Prawdziwymi wierszami wyniku są te, które łączą nazwisko pracownika z nazwą i lokalizacją tego departamentu, w którym jest faktycznie zatrudniony. A skoro w wyniku są połączone nazwiska WSZYSTKICH pracowników z danymi WSZYSTKICH departamentów, stąd prosty wniosek, że wynik zawiera prawdziwe rekordy. Trzeba je tylko znaleźć.
Każdy rekord w tabeli DEPT zawiera znaczącą wartość Deptno – klucz główny. Każdy rekord pracownika w tabeli EMP zawiera wartość Deptno, klucz obcy, wskazujący na numer departamentu, w którym dany pracownik jest zatrudniony. Zatem aby z wyniku naszego zapytania odczytać rekordy prawdziwe, należy do polecenia dodać sformułowany powyżej warunek równości wartości Deptno w obu tabelach. Obecnie nasze polecenie będzie wyglądało następująco:
Wypisz nazwiska pracowników (Ename), wraz z nazwami (Dname) i lokalizacjami (Loc) departamentów, w których są zatrudnieni, deklarując warunek złączenia tabel w klauzuli WHERE.
SELECT Ename, Dname, Loc FROM EMP, DEPT WHERE EMP.Deptno = DEPT.Deptno;
Tym razem w wyniku pojawi się 14 wierszy, czyli tyle, ilu jest w tabeli EMP zapisanych pracowników. Zatem będą to tylko wiersze zawierające prawdziwe informacje. Będą to dane pracowników, wraz z nazwami i lokalizacją departamentów, w których są zatrudnieni. Jeżeli w tabeli DEPT istnieją rekordy, opisujące departamenty, których numer (Deptno) nie występuje w rekordach tabeli żadnych pracowników, ich dane w wyniku się nie pojawią. Jeżeli w tabeli EMP znajdują się rekordy opisujące pracowników, które w kolumnie Deptno mają wartość NULL (nie są przypisani do żadnego departamentu), ich dane w wyniku się nie pojawią.
Wyjaśnienie zamieszczone w poprzednim akapicie dotyczy przypadku, w którym we wszystkich wierszach w kolumnie Deptno tabeli EMP znajdują się wartości znaczące, będące elementami zbioru wartości klucza głównego Deptno tabeli DEPT. W naszym przykładzie (tabela EMP przedstawiona w wykładzie 4) tak nie jest - w rekordzie pracownika o numerze 7369, w kolumnie Deptno jest warość NULL. Stąd też w takim przypadku, w wyniku powyższej instrukcji SELECT zostanie zwrócone 13 wierszy.
To jest przykład złączenia dwóch tabel. Jeżeli zachodzi potrzeba złączenia
więcej niż dwóch tabel, w klauzuli WHERE muszą znaleźć się wszystkie warunki
definiujące warunki powiązań wszystkich tabel wchodzących w skład zapytania.
Jedna sprawa wymaga jeszcze wyjaśnienia. Dotychczas, odczytując dane z jednej
tabeli, nigdy nie mieliśmy do czynienia z niejednoznacznością nazw kolumn.
Zgodnie z postulatami Codd’a nazwy kolumn w każdej tabeli muszą być
jednoznaczne. Jednak nazwy kolumn w różnych tabelach mogą się powtarzać, przy
spełnionym postulacie zachowania unikalności nazw tabel. Aby w przypadku
odwoływania się w zapytaniu do tabel, w których występują jednakowe nazwy
kolumn, zachować wymaganą jednoznaczność, powtarzające się nazwy poprzedzane są
(mówimy też: kwalifikowane) nazwami tabel, co oczywiście gwarantuje
jednoznaczność. W przypadku kolumn o nazwach jednoznacznych w obrębie zapytania,
poprzedzająca nazwa tabeli może się pojawić, ale także może zostać pominięta. Ta
zasada dotyczy wszystkich klauzul.
Podsumowując przedstawioną powyżej metodę dochodzenia do prawidłowego wyniku zapytania, można sobie wyobrazić dwuetapowy schemat jego wykonania. W pierwszym etapie tworzony jest iloczyn kartezjański na zbiorach rekordów wszystkich rekordów tabel, na których operuje instrukcja SELECT, w drugim etapie, eliminowane są z niego te rekordy, dla których klauzula WHERE nie przyjmuje wartości TRUE. Oczywiście w klauzuli WHERE mogą się pojawić, powiązane operatorami w jedną całość, zarówno warunki powiązania tabel, jak też inne warunki ograniczające zwracane przez instrukcję rekordy.
Istnieje inny, przewidziany przez składnię języka SQL sposób wskazywania w instrukcji SELECT sposobu złączenia tabel. W swojej idei odwołuje się on do definicji związku tabel (więzów referencyjnych – zostaną one omówione w dalszej części wykładu). Składnia tej metody pozwala na wskazanie w klauzuli FROM tabel, które są ze sobą złączane, jak również kolumn, które to złączenie realizują. Z reguły są to kolumny klucza głównego tabeli nadrzędnej i odpowiadającego mu klucza obcego tabeli podrzędnej. W ogólności mogą to być dowolne kolumny, o tych samych typach danych (typy mogą być konwertowane). Składnia tej definicji powiązania wygląda następująco:
Tab1 JOIN Tab2 ON Tab1.Kol1 = Tab2.Kol2
gdzie T1 i T2 to tabele, z których dane będą odczytywane, Kol1 i Kol2 kolumny realizujące powiązanie tabel.
Złączenie tabel definiowane przez JOIN może występować w następujących wariantach:
INNER JOIN
LEFT [OUTER] JOIN
RIGHT [OUTER] JOIN
FULL [OUTER] JOIN
Najczęściej używanym wariantem łączenia tabel przy użyciu omawianej składni jest INNER JOIN, realizujący następującą odczytaj z bazy i włącz do rozwiązania wszystkie rekordy ze wskazanych w JOIN tabel, dla których wartości w kolumnach wskazanych w ON są sobie równe.
Wypisz nazwiska pracowników (Ename), wraz z nazwami (Dname) i lokalizacjami (Loc) departamentów, w których są zatrudnieni, deklarując warunek złączenia tabel poprzez JOIN.
SELECT Ename, Dname, Loc FROM EMP INNER JOIN DEPT ON EMP.Deptno = DEPT.Deptno;
Powyższy przykład jest równoważny poprzedniemu, wykorzystującemu do związania tabel klauzulę WHERE, czyli włącza do wyniku te wiersze z tabel Tab1 i Tab2, dla których Tab1.Kol1 są równe wartościom Tab2.Kol2. Wyklucza to, oczywiście, rekordy z dowolnej z tabel Tab1 lub Tab2, w których w kolumnie Tab1.Kol1 lub Tab2.Kol2 znajdują się wartości NULL (porównanie jakiejkolwiek wartości z NULL daje w wyniku NULL, a do wynikowego zestawu rekordów włączane są tylko te, dla których wartość logiczna porównania kolumn jest TRUE, odrzucane są te, dla których ta wartość jest FALSE lub NULL).
W przypadku, gdy instrukcja SELECT odwołuje się do większej niż dwie liczby tabel, składnia definicji związku wygląda następująco:
SELECT W1, W2, …. FROM T1 INNER JOIN T2 ON T1.K1 = T2.K2 INNER JOIN T3 ON T2.K3 = T3.K3 INNER JOIN ... ON ...
Natomiast w sytuacji, gdy związek dwóch tabel zdefiniowany jest na więcej niż jednej parze kolumn (klucz główny tabeli nadrzędnej i klucz obcy tabeli podrzędnej są kluczami złożonymi), składnia definicji związku musi tą złożoność uwzględnić:
SELECT W1, W2, …. FROM T1 INNER JOIN T2 ON T1.K1 = T2.K2 AND T1.K3 = T2.K4
gdzie K1 i K3 to kolumny złożonego klucza głównego tabeli nadrzędnej T1,
kolumny K2 i K4 to kolumny złożonego klucza obcego tabeli podrzędnej T2.
Podsumowując, istotę wiązania tabel poprzez INNER JOIN można
sformułować następująco: odczytaj z tabel powiązanych INNER JOIN
tylko te rekordy, dla których wartości w kolumnach wskazanych przez
ON są równe w obu tabelach.
Warto zwrócić uwagę na fakt, że rozdzielenie warunków złączenia tabel (przez
zadeklarowanie ich poprzez INNER JOIN) od warunków
ograniczających (deklarowanych w klauzuli WHERE) czyni całość
kodu znacznie czytelniejszą, niż umieszczenie w klauzuli WHERE
zarówno warunków złączeń jak i warunków ograniczających.
Zastanówmy się chwilę, co naprawdę oznacza podana powyżej reguła, dotycząca odczytywania danych z tabel powiązanych INNER JOIN. Załóżmy, że w ON podane są kolumny odpowiednio klucza głównego tabeli nadrzędnej i powiązanego z nim klucza obcego tabeli podrzędnej (jest to najczęściej spotykany przypadek, aczkolwiek nie jedyny możliwy). W tym przypadku w wyniku, każda wartość klucza głównego tabeli nadrzędnej pojawi się tyle razy, ile razy została użyta w roli klucza obcego tabeli podrzędnej. Natomiast patrząc od strony tabeli podrzędnej, nie pojawią się w wyniku te rekordy, dla których wartość kolumny klucza obcego jest NULL (zakładamy, że nie mogą się tam pojawić wartości nieużyte w roli klucza głównego tabeli nadrzędnej).
Drugim, obok INNER JOIN sposobem złączania tabel jest OUTER JOIN (słowo OUTER jest opcjonalne, może zostać opuszczone). OUTER JOIN występuje w trzech wariantach: LEFT, RIGHT i FULL. Konstrukcja ta używana jest w celu włączenia do wynikowych rekordów złączenia tabel, także tych rekordów, których nie włącza INNER JOIN. Dyrektywa OUTER JOIN umożliwia odczytanie ze wskazanych tabel zarówno powiązanych, jak też niepowiązanych rekordów i występuje w trzech wariantach:
LEFT [OUTER] JOIN (lewostronne złączenie zewnętrzne) – do wyniku włączane są rekordy, dla których wartości powiązanych pól w obu tabelach są równe, (czyli tak, jak w INNER JOIN), oraz wszystkie pozostałe rekordy z tabeli wymienionej po lewej stronie słów LEFT JOIN. Zatem wracając do powyższego przykładu:
Wypisz nazwiska (Ename) wszystkich pracowników wraz z nazwami (Dname) i lokalizacjami (Loc) departamentów, w których są zatrudnieni. Uwzględnij także tych pracowników, którzy nie zostali przypisani do żadnego departamentu (w kolumnie Deptno opisującego ich rekordu jest wartość Null).
SELECT Ename, Dname, Loc FROM EMP LEFT JOIN DEPT ON EMP.Deptno = DEPT.Deptno;
Tym razem w wyniku pojawią się wszystkie wiersze pracowników oraz zatrudniających ich departamentów, ale także dane tych pracowników, którzy nie są zatrudnieni w żadnym z departamentów (w polach Dname i Loc pojawi się w wyniku NULL).
RIGHT [OUTER] JOIN (prawostronne złączenie zewnętrzne, symetryczne dla złączenia lewostronnego) – do wyniku włączane są rekordy, dla których wartości powiązanych pól w obu tabelach są równe, (czyli tak, jak w INNER JOIN), oraz wszystkie pozostałe rekordy z tabeli wymienionej po prawej stronie słów RIGHT JOIN. Teraz nasz przykład zdefiniujemy następująco:
Wypisz nazwiska (Ename) wszystkich pracowników wraz z nazwami (Dname) i lokalizacjami (Loc) departamentów, w których są zatrudnieni. Uwzględnij także te departamenty, w których nikt nie jest zatrudniony (wartość Deptno nie występuje w żadnym rekordzie tabeli EMP).
SELECT Ename, Dname, Loc FROM EMP RIGHT JOIN DEPT ON EMP.Deptno = DEPT.Deptno;
Tym razem w wyniku pojawią się wszystkie wiersze pracowników oraz zatrudniających ich departamentów, ale także dane tych departamentów, w których nie są zatrudnieni pracownicy (w polu Ename pojawi się w wyniku NULL).
FULL [OUTER] JOIN (pełne złączenie zewnętrzne) – jest sumą, (ale bez powtórzeń) wyników LEFT i RIGHT. Do wyniku włączane są rekordy, dla których wartości powiązanych pól w obu tabelach są równe, (czyli tak, jak w INNER JOIN), oraz wszystkie pozostałe rekordy z tabel wymienionych po obu stronach słów FULL JOIN. W naszym przykładzie:
Wypisz nazwiska (Ename) wszystkich pracowników wraz z nazwami (Dname) i lokalizacjami (Loc) departamentów, w których są zatrudnieni. Uwzględnij także te departamenty, w których nikt nie jest zatrudniony (wartość Deptno nie występuje w żadnym rekordzie tabeli EMP), a także tych pracowników, którzy nie zostali przypisani do żadnego departamentu (w kolumnie Deptno opisującego ich rekordu jest wartość Null).
SELECT Ename, Dname, Loc FROM EMP FULL JOIN DEPT ON EMP.Deptno = DEPT.Deptno;
Teraz w wyniku pojawią się wszystkie wiersze pracowników oraz zatrudniających ich departamentów, ale także dane tych departamentów, w których nie są zatrudnieni pracownicy (w polu Ename pojawi się w wyniku NULL) oraz dane tych pracowników, którzy nie są zatrudnieni w żadnym z departamentów (w polach Dname i Loc pojawi się w wyniku NULL).
Uzyskanie wyniku tożsamego z wynikiem FULL JOIN jest możliwe także poprzez inną konstrukcję (UNION), omówiona w dalszej części wykładu. Jednak wariant FULL JOIN został włączony do składni z uwagi na zachowanie jej spójności.
Należy jeszcze wspomnieć, że ORACLE implementuje jeszcze inny zapis, realizujący złącznie jednostronne:
SELECT Ename, Dname, Loc FROM EMP, DEPT WHERE EMP.Deptno (+)= DEPT.Deptno;
Powyższa formuła jest równoważna z zapisem
SELECT Ename, Dname, Loc FROM EMP RIGHT JOIN DEPT ON EMP.Deptno = DEPT.Deptno;
W wyniku zwracane są wszystkie rekordy tabeli DEPT, oraz te rekordy tabeli EMP, dla których wartości wiążących pól Deptno są równe.
Dotychczas zostały przedstawione sposoby utworzenia związków tabel w oparciu o równość wartości zapisanych w porównywanych kolumnach. Nie jest to jednak jedyna możliwość. Co więcej, można sformułować regułę, że prawidłowa jest każda konstrukcja, usuwająca z iloczynu kartezjańskiego (wyprodukowanego na wszystkich rekordach wszystkich tabel wymienionych w klauzuli SELECT) te rekordy, które zawierają nieprawdziwe dane.
Jako przykład posłuży nam związek tabel EMP i SALGRADE. Tabele te, jak to już było wcześniej omówione, nie są powiązane poprzez układ klucz główny – klucz obcy. Jeżeli utworzymy iloczyn kartezjański wszystkich rekordów z obu tabel, będzie on zawierał rekordy wszystkich pracowników (także ich miesięczną płacę Sal) w połączeniu ze wszystkimi rekordami tabeli SALGRADE, zawierającymi wartości płacy maksymalnej (Maxsal), minimalnej (Minsal) oraz numer grupy zaszeregowania. Liczba wynikowych rekordów będzie równa wynikowi przemnożenia liczby rekordów tabeli EMP przez liczbę rekordów tabeli SALGRADE. Ponieważ wynik ten zawiera wszystkie wartości płac w połączeniu ze wszystkimi grupami zarobkowymi, zatem zawiera także te, które odpowiadają właściwej grupie zarobkowej. Z omówienia zawartości tabel EMP i DEPT wynika, że każda płaca Sal mieści się w przedziale pomiędzy Minsal i Maxsal z tabeli SALGRADE, co odpowiada jednej grupie zarobkowej. Zatem wystarczy umieścić ten warunek w klauzuli WHERE, aby uzyskać prawidłowy wynik.
Wypisz nazwiska (Ename), ich płace (Sal) oraz grupę zaszeregowania (Grade) wszystkich pracowników.
SELECT Ename, Sal, Grade FROM EMP, SALGRADE WHERE Sal BETWEEN Losal AND Hisal;
Identyczny rezultat uzyskamy, używając warunku złączenia definiowanego w JOIN:
SELECT Ename, Sal, Grade FROM EMP INNER JOIN SALGRADE ON Sal BETWEEN Losal AND Hisal;
Dopuszczalność, w relacyjnym modelu danych, istnienia związków rekurencyjnych, czyli możliwość tworzenia związku jednoznacznego na jednej tabeli, będącej jednocześnie stroną jeden i stroną wiele tego związku, implikuje możliwość odczytu danych zapisanych z użyciem takiego związku. Ponieważ nazwa tabeli musi być przy zapisie użyta zarówno w roli tabeli nadrzędnej, jak i podrzędnej, zatem w celu zachowania wymaganej jednoznaczności nazw tabel, należy używać aliasów ich nazw.
Wypisz nazwiska (Ename) pracowników, oraz nazwiska (Ename) ich szefów.
SELECT K.Ename Szef, P.Ename Pracownik FROM EMP K INNER JOIN EMP P ON K.Empno = P.Mgr;
Jak to zostało opisane w Wykładzie I, w tabeli EMP każdy pracownik (jego wiersz) identyfikowany jest wartością klucza głównego Empno, a jego przełożonego (szefa) wskazuje wartość w kolumnie Mgr, będąca kluczem obcym. Zatem zrealizowany jest związek rekurencyjny na tabeli EMP. Aby z niego skorzystać, należy dwukrotnie odwołać się do tabeli EMP, gdyż występuje ona po obu stronach związku. Z uwagi na konieczność zachowania jednoznaczności nazw, należy użyć aliasu nazwy tabel (w powyższym przykładzie zostały użyte aliasy „obu” tabel, choć wystarczyłby tylko jeden). Po wykonaniu tego zabiegu, można odwołać się w klauzuli SELECT oraz w warunku złączenia ON do „rozmnożonej” tabeli EMP, raz występującej pod nazwą K (z tej tabeli odczytujemy dane szefów), a raz pod nazwą P (z tej tabeli odczytujemy dane pracowników).
Podsumowując zagadnienia związane z odczytywaniem danych z wielu tabel, należy podkreślić, że poza bardzo nielicznymi przypadkami, prawidłowy wynik uwarunkowany jest zdefiniowaniem warunków złączenia tabel. Można powiedzieć, że w wyniku wymienienia w klauzuli SELECT nazw tabel, z których dane będą odczytywane, tworzona jest wirtualna tabela, zawierająca wyłącznie te rekordy, które pozostały po usunięciu z iloczynu kartezjańskiego utworzonego na wszystkich rekordach wymienionych tabel, tych rekordów, które nie spełniają warunków złączenia i warunków ograniczających zadeklarowanych w JOIN i/lub w klauzuli WHERE. Ta wirtualna tabela tworzona (koncepcyjnie), tylko w celach odczytu danych, nie ma żadnego wpływu (nie zmienia, nie narusza) na zasadniczą strukturę bazy danych, zdefiniowaną poprzez tabele oraz więzy integralności (omówienie w dalszej części wykładu). W dalszej części wykładu przyjmiemy, że nie ma znaczenia fakt, na ilu tabelach wykonywana jest operacja. Istotna jest prawidłowość ich złączeń, dająca w wyniku RELACJĘ, na której dalsze operacje będą wykonywane.
Wyniki instrukcji SELECT mogą być traktowane, jako zbiory rekordów. Na dwóch, lub większej liczbie wyników można wykonywać operacje dopuszczalne na zbiorach – sumy, różnicy i przecięcia (iloczynu) zbiorów. Warunkiem wykonalności tych operacji, jest jednakowa struktura wszystkich zbiorów wyników, biorących w niej udział. Przez jednakową strukturę rozumiemy, że każdy zbiór zawiera identyczną liczbę wynikowych kolumn, identycznie uporządkowanych, a każda kolumna zawiera wartości o identycznym typie danych.
Operatory realizujące te operacje to odpowiednio:
UNION [ALL] – suma zbiorów wyników INTERSECT – iloczyn (przecięcie) zbiorów wyników EXCEPT / MINUS – różnica zbiorów wyników (EXCEPT jest przewidziany przez standard języka SQL, MINUS zaimplementowany w ORACLE).
Krótkie przypomnienie pojęć z teorii mnogości:
I jeszcze uściślenie sposobu działania operatora UNION. W wyniku jego użycia zwracany jest zbiór wynikowych rekordów bez powtórzeń (rekordy powtarzające się zwracane są tylko jeden raz), czyli zwracany jest wynik ściśle odpowiadający definicji sumy zbiorów. Natomiast użycie opcjonalnego rozszerzenia ALL wstrzymuje eliminację powtórzeń – do wynikowego zbioru rekordów wchodzą wszystkie rekordy występujące w zbiorach wyjściowych.
Poniżej przedstawiamy trzy proste przykłady prezentujące działanie operatorów algebraicznych.
Wypisz stanowiska (job) pracowników z działów 10 i 30.
SELECT Job FROM EMP WHERE Deptno = 10 UNION SELECT Job FROM EMP WHERE Deptno = 30;
Użycie w powyższym przykładzie operatora UNION ALL spowoduje wypisanie każdego stanowiska tyle razy, ilu pracowników z działów 10 i 30 łącznie, jest na tym stanowisku zatrudnionych.
Wypisz stanowiska (job) występujące zarówno w dziale 10 jak i 30.
SELECT Job FROM EMP WHERE Deptno = 10 INTERSECT SELECT Job FROM EMP WHERE Deptno = 30;
Wypisz stanowiska (job) występujące w dziale 10, a niewystępujące w dziale 30.
SELECT Job FROM EMP WHERE Deptno = 10 EXCEPT SELECT Job FROM EMP WHERE Deptno = 30;
Tabelom użytym w konstrukcji zapytania, można zmienić nazwy, czyli nadać aliasy. Tak jak w przypadku aliasów kolumn, alias może występować w postaci prostego identyfikatora, czyli napisu złożonego z liter, cyfr i znaków podkreślenia. Identyfikator ograniczony różni się od identyfikatora prostego tym, że MOŻE zawierać spacje i MUSI być ujęty w podwójne cudzysłowy. W przypadku aliasowania nazw tabel praktycznie nie używa się identyfikatorów ograniczonych. Alias może zostać poprzedzony słowem AS przewidzianym przez standard języka, dopuszczalnym, ale niewymaganym w większości implementacji.
Oczywiście zmiana nazwy tabeli poprzez użycie aliasu, dotyczy tylko tej
instrukcji SELECT, w której został on zdefiniowany.
O ile użycie aliasów nazw wyrażeń w klauzuli SELECT jest na ogół spowodowane
wygodą użytkownika, lub dążeniem do elegancji wyniku, o tyle używanie aliasów
nazw tabel jest konieczne w przypadku wielokrotnych odwołań do jednej tabeli w
przypadku związków rekurencyjnych i podzapytań skorelowanych, omawianych w
jednym z kolejnych rozdziałów.
W przypadku odwoływania się do tabel z innych schematów, lub baz danych, użycie aliasów nazw tabel pozwala radykalnie skrócić całość nazwy, zawierającą nazwę bazy, schematu i tabeli. To zagadnienie zostanie szerzej omówione w wykładzie z przedmiotu Administrowanie Bazami Danych.