MS SQL odczytywanie danych
W artykule MS SQL odczytywanie danych znajdziesz informacje na temat podstawowej składni języka MS SQL.
Zapytania w artykule prezentujemy na podstawie baz AdventureWorks i Northwind.
MS SQL odczytywanie danych
Relacyjna baza danych to zbiór danych o ściśle określonej strukturze. Dane przechowywane są w wielu odrębnych, ale powiązanych ze sobą tabelach.
Tabela zbudowana jest z pionowych kolumn i poziomych wierszy. Na ich przecięciu znajdują się komórki.
W poszczególnych kolumnach tabeli powinny znajdować się dane tego samego typu np. w kolumnie Nazwisko powinny być przechowywane nazwiska, w kolumnie Data urodzenia powinny być przechowywane tylko daty urodzenia.
Każdy rekord tabeli składa się z takiej samej liczby kolumn.
Kolumny w przykładowej tabeli Person.PersonPhone w bazie AdventureWorks.
Informacje w tabeli Person.PersonPhone
Przykłady kodu prezentowane w artykule możesz uruchomić w bazie AdventureWorks lub Northwind.
Informacje na temat, w jaki sposób zainstalować środowisko SQL Server oraz bazy danych znajdziesz w artykule SQL Server instalacja
Typy danych
Dane mogą reprezentować m.in. takie elementy jak imiona, nazwiska, opisy, liczby, obrazy, dokumenty.
Typy danych:
- mogą obejmować dane tekstowe (ciągi znaków), liczby, daty i godziny, obrazy (*.jpg) i inne dane binarne (*.zip)
- określają sposób przechowywania danych – decydują, czy w danej kolumnie mogą być zapisywane dane alfanumeryczne, numeryczne, daty i czasu.
Każda implementacja SQL może mieć swoje własne, niestandardowe typy danych oraz własne nazwy dla standardowych typów danych.
Ciągi znaków (teksty) i daty muszą być ujęte w znaki apostrofu. Wartości numeryczne (liczby) nie powinny być wpisywane w apostrofach.
SELECT * FROM Person.PersonPhone WHERE PhoneNumberTypeID = 1 AND PhoneNumber = '612-555-0100' AND ModifiedDate = '20071128';
Datę należy podawać w formacie „yyyyMMdd” np. „20071128”. Format ten jest właściwie interpretowany przez SQL Server niezależnie od ustawień regionalnych komputera.
Podstawowe typy danych liczbowych:
Typ danych | Opis |
---|---|
INTEGER(INT) | reprezentuje liczby całkowite |
NUMERIC(DECIMAL) | reprezentuje liczby o określonej skali i precyzji |
REAL | reprezentuje liczby o zmiennej precyzji |
FLOAT | reprezentuje liczby zmiennoprzecinkowe |
Podstawowe typy daty i czasu:
Typ danych | Opis |
---|---|
DATETIME | reprezentuje datę i czas |
DATE | reprezentuje datę |
TIME | reprezentuje czas |
Podstawowe typy znakowe:
Typ danych | Opis |
---|---|
CHAR | reprezentuje ciągi znaków o stałej długości, uzupełniając krótsze wartości spacjami |
VARCHAR | reprezentuje ciąg znaków o zmiennej długości |
NCHAR,NVARCHAR | reprezentuje ciąg znaków o stałej lub zmiennej długości zakodowanych w UNICODE (obsługa polskich znaków) |
Operatory
W języku SQL używamy operatorów:
- arytmetycznych – dodawanie, odejmowanie, mnożenie, dzielenie, dzielenie modulo
- porównania – równe, większe niż, mniejsze niż, większe lub równe, mniejsze lub równe, różne
- SQL – IN, BETWEEN …AND, LIKE, IS NULL
- logicznych – AND, OR, NOT
Operatorów używamy najczęściej w klauzulach WHERE i HAVING w instrukcji SELECT.
Logika trójwartościowa
W serwerach bazodanowych występuje wartość specjalna NULL. Reprezentuje ona brak danych w polu tabeli.
Ze względu na występowanie wartości specjalnej NULL, w SQL obowiązuje logika trójwartościowa. Wynikiem wyrażenia logicznego może być wartość TRUE, FALSE lub UNKNOWN.
Przykład:
- 1 + 1 = 2 –> TRUE
- 1 + 1 = 3 –> FALSE
- 1 + NULL = UNKNOWN –> UNKNOWN
Więcej informacji na temat operatorów i logiki trójwartościowej znajdziesz w artykule pod linkiem MS SQL – operatory
Odczytywanie danych – instrukcja SELECT
Poniżej zapytanie SQL, za pomocą którego możesz:
- odczytać z bazy dane z dwóch tabel
- ograniczyć liczbę wybieranych rekordów
- pogrupować wybrane rekordy
- ograniczyć liczbę grup
- posortować wybrane grupy
SELECT LastName, COUNT(*) FROM [Person].[EmailAddress] a JOIN Person.Person b ON a.BusinessEntityID = b.BusinessEntityID WHERE a.BusinessEntityID < 100 GROUP BY LastName HAVING COUNT(*) > 2 ORDER BY LastName;
Zastosowanie poszczególnych klauzul:
- SELECT – wskazujemy kolumny, które chcemy otrzymać w wyniku
- FROM – wskazujemy tabelę, z której chcemy odczytać dane
- JOIN – wskazujemy nazwę tabeli, którą chcemy dołączyć
- ON – wskazujemy kolumny, według których będziemy dokonywać złączenia
- WHERE – filtr dla wybieranych wierszy
- GROUP BY – wskazujemy kolumny, według których ma się odbywać grupowanie
- HAVING – filtr dla wybieranych grup
- ORDER BY – wskazujemy kolumny, według których ma się odbywać sortowanie
Kolejność klauzul w każdym zapytaniu musi być dokładnie taka, jak w powyższym przykładzie.
Nie każde zapytanie wymaga użycia wszystkich klauzul. Niektóre z nich możesz pomijać np. jeśli nie łączysz tabel, nie potrzebujesz klauzuli JOIN … ON. Jeśli nie grupujesz danych, nie będzie Ci potrzebna klauzula GROUP BY itd.
Poniżej znajdziesz przykłady, które możesz wykorzystać do rozpoczęcia samodzielnego pisania prostych zapytań i odczytywania danych z bazy.
Odczytanie wszystkich kolumn i wierszy z jednej tabeli
Dane odczytujemy z tabeli Person.Person. Aby odczytać (wyświetlić) wszystkie kolumny wstawiamy symbol gwiazdki (*).
SELECT * FROM Person.Person;
Odczytanie wybranych kolumn i wszystkich wierszy z jednej tabeli
Aby odczytać wybrane kolumny, wypisujemy ich nazwy. Z tabeli Person.Person odczytujemy imię (FirstName) i nazwisko (LastName) oraz wszystkie rekordy.
SELECT FirstName, LastName FROM Person.Person;
Odczytanie wybranych wierszy
Aby odczytać tylko niektóre wiersze używamy klauzuli WHERE.
Klauzula WHERE umożliwia filtrowanie zwracanych przez zapytanie wierszy. Umieszczone w niej warunki logiczne są sprawdzane dla każdego wiersza tabeli. Jeśli wynikiem testu logicznego jest PRAWDA, wiersz trafia do wyniku zapytania. Jeżeli wynikiem jest FAŁSZ lub WARTOŚĆ NIEZNANA, wiersz nie jest uwzględniony w wyniku.
W przykładzie z tabeli Person.Person wybrany zostanie tylko ten wiersz, dla którego w kolumnie BusinessEntityID jest wartość równa 1702.
SELECT * FROM Person.Person WHERE BusinessEntityID = 1702;
Ograniczenie liczby zwracanych wierszy
Ograniczenie liczby wierszy zwróconych w zapytaniu umożliwia klauzula TOP. W klauzuli TOP ilość wierszy, którą chcemy otrzymać w wyniku, może być określona procentowo np. 10 PERCENT lub bezwzględnie za pomocą liczby np. 10.
Poniższe zapytanie zwróci 3 wiersze
SELECT TOP 3 * FROM Person.Person;
Poniższe zapytanie zwróci 3% wierszy
SELECT TOP 3 PERCENT * FROM Person.Person;
Wyeliminowanie z wyniku zapytania duplikatów
Powtarzające się dane (duplikaty) możemy wyeliminować z wyniku zapytania za pomocą słowa kluczowego DISTINCT.
SELECT DISTINCT FirstName, LastName FROM Person.Person;
Łączenie ciągów znaków
W instrukcji SELECT można umieszczać stałe i łączyć ciągi znaków. W poniższym zapytaniu łączymy imię (FirstName) i Nazwisko (LastName) i wstawiamy pomiędzy nie stałą (w tym przypadku jest to spacja).
SELECT DISTINCT FirstName, LastName, FirstName + ' '+ LastName FROM Person.Person;
Komentarze
Komentarzy używamy do dokumentowania kodu lub wyłączania partii kodu z części wykonywanej przez silnik bazodanowy. Kod umieszczony w komentarzu jest ignorowany podczas wykonywania zapytania.
SQL Server obsługuje dwa typy znaków komentarza:
- podwójne myślniki – wszystko od podwójnych myślników do końca linii jest częścią komentarza i jest pomijane.
SELECT * FROM Person.Person --tabela z klientami --WHERE FirstName = 'Ken'
- para znaków z ukośnikiem w przód – cały kod pomiędzy otwartym i zamkniętym znakiem komentarza jest pomijany.
SELECT * FROM Person.Person WHERE FirstName = 'Ken' /*AND LastName like 'M%' AND Gender = 'M' */;
Wygodnym sposobem komentowania kodu jest użycie przycisków znajdujących się na pasku narzędzi w edytorze SQL Server Management Studio
Aliasy kolumn
Alias kolumny umożliwia chwilową zmianę nazwy kolumny w ramach danego zapytania. Słowo kluczowe AS jest opcjonalne.
SELECT SalesYTD AS wyniki FROM Sales.SalesTerritory;
Aliasy tabel
Aliasy tabel definiujemy w klauzuli FROM. Po zdefiniowaniu aliasu dla tabeli, w pozostałych klauzulach zapytania nie możemy już używać oryginalnej nazwy tabeli. Musimy używać aliasu. Słowo kluczowe AS jest opcjonalne.
Aliasy tabel są szczególnie przydatne w przypadku łączenia tabel. Dzięki aliasom nie musimy podawać w zapytaniu pełnej nazwy tabeli.
SELECT ST.SalesYTD as wyniki FROM Sales.SalesTerritory as ST;
Sortowanie wyników zapytań
Wyniki zapytań możemy sortować według jednej kolumny lub według wielu kolumn. Kolejność, w jakiej kolumny są wymienione w klauzuli ORDER BY wyznacza kolejność sortowania.
SELECT FirstName, LastName FROM Person.Person ORDER BY FirstName;
SELECT FirstName, LastName FROM Person.Person ORDER BY FirstName, LastName;
Domyślnie dane sortowane są rosnąco. Aby zmienić porządek sortowania możemy użyć modyfikatora DESC.
SELECT FirstName, LastName FROM Person.Person ORDER BY FirstName DESC;
Złożone warunki logiczne
Wszystkie operatory porównania możemy łączyć ze sobą za pomocą operatorów logicznych AND, OR. Dzięki temu możemy tworzyć rozbudowane zapytania.
SELECT * FROM Person.Person WHERE (LastName LIKE 'B%' OR LastName LIKE 'C%') AND PersonType = 'EM' AND EmailPromotion = 1;
W przykładzie wyszukujemy z tabeli Person.Person tylko te rekordy, w których:
- Nazwisko (LastName) zaczyna się na literę B lub na literę C
- Dane w kolumnie Typ klienta (PersonType) to „EM”
- Dane w kolumnie Promocja e-mailowa (EmailPromotion) to 1
Funkcje wbudowane
funkcja CEILING() – zaokrąglenie w górę
SELECT Freight, CEILING(Freight) FROM Orders;
funkcja FLOOR() – zaokrąglenie w dół
SELECT Freight, FLOOR(Freight) FROM Orders;
funkcja ROUND() – zaokrąglenie liczby do określonej, przez drugi argument wywołania, liczby miejsc po przecinku
SELECT Freight, ROUND(Freight, 1) FROM Orders;
W przykładzie liczba zaokrąglona zostanie do jednego miejsca po przecinku.
funkcja LEN() – obliczenie długości przekazanego ciągu znaków
SELECT ShipCity, LEN(ShipCity) FROM Orders;
funkcja LTRIM() – usunięcie wiodących spacji
SELECT ShipCity, LTRIM(ShipCity) FROM Orders;
funkcja RTRIM() – usunięcie spacji z prawej strony ciągu znaków
SELECT ShipCity, RTRIM(ShipCity) FROM Orders;
funkcje LEFT() i RIGHT() – zwrócenie wskazanej liczby znaków z lewej lub z prawej strony tekstu
SELECT ProductNumber, LEFT(ProductNumber,2) FROM Production.Product;
SELECT ProductNumber, RIGHT(ProductNumber,4) FROM Production.Product;
funkcja SUBSTRING() – zwrócenie części ciągu znaków o określonej długości (zaczynając od znaku o podanej pozycji)
SELECT ShipCity, SUBSTRING(ShipCity,1,3) FROM Orders;
W przykładzie z danych w kolumnie ShipCity wyświetlamy 3 znaki zaczynając od znaku pierwszego.
funkcje UPPER() i LOWER() – zwrócenie tekstu zamienionego na duże lub na małe litery
SELECT ShipCity, UPPER(ShipCity) FROM Orders;
SELECT ShipCity, LOWER(ShipCity) FROM Orders;
funkcja DATEADD() – zwrócenie daty i czasu zwiększonego o podaną liczbę wskazanych jednostek
SELECT OrderDate, DATEADD(Day,2,OrderDate) FROM Orders;
W przykładzie do daty w kolumnie OrderDate dodajemy 2 dni.
funkcja DATEDIFF() – zwrócenie liczby jednostek dzielących przekazane jako argumenty daty
SELECT RequiredDate, OrderDate, DATEDIFF(Day,OrderDate, RequiredDate) FROM Orders;
W przykładzie wyliczamy w dniach różnicę pomiędzy datami znajdującymi się w kolumnie OrderDate i datami znajdującymi się w kolumnie RequiredDate.
funkcje DAY(), MONTH(), YEAR() – zwrócenie numeru dnia, miesiąca lub roku z przekazanej jako argument daty
SELECT OrderDate, DAY(OrderDate) FROM Orders;
SELECT OrderDate, MONTH(OrderDate) FROM Orders;
SELECT OrderDate, YEAR(OrderDate) FROM Orders;
funkcja GETDATE() – zwrócenie bieżącej daty i czasu
SELECT GETDATE();
Konwersja typów danych
Za pomocą funkcji CAST i CONVERT można określić jawną konwersję danych.
Funkcja CONVERT różni się od funkcji CAST tym, że można w niej określić styl typu danych. Jest to przydatne przy konwersji na typy danych daty i czasu.
SELECT SalesYTD, CAST(SalesYTD as VARCHAR(100)) FROM Sales.SalesTerritory;
W przykładzie konwertujemy typ danych money na typ danych varchar (tekstowy).
SELECT SalesYTD, CONVERT(varchar(10), ModifiedDate, 120) as [date] FROM Sales.SalesTerritory;
W przykładzie konwertujemy datę na typ tekstowy. W trzecim argumencie za pomocą liczby 120 podajemy, w jakim formacie ma być zwrócona data.
Wyrażenie CASE
Wyrażenie CASE ocenia listę warunków i zwraca jedno z możliwych wyrażeń wynikowych:
- jeśli określony w klauzuli WHEN warunek jest prawdziwy, wykonywany jest blok instrukcji THEN, w przeciwnym razie wykonywane są instrukcje z bloku ELSE.
- kolejne warunki logiczne (klauzule WHEN) są sprawdzane w kolejności, w jakiej zostały zapisane. Po znalezieniu pierwszego prawdziwego warunku, funkcja CASE zwraca odpowiadającą mu wartość i nie sprawdza dla tego wiersza kolejnych warunków.
SELECT [TerritoryID], SalesYTD, CASE WHEN SalesYTD < 5000000 THEN 'słabo' WHEN SalesYTD <= 6000000 THEN 'ok' ELSE 'kosmiczna sprzedaż' END FROM Sales.SalesTerritory order by SalesYTD;
W przykładzie:
- w pierwszym warunku sprawdzamy, czy wartość w kolumnie SalesYTD jest mniejsza niż 5 mln. Jeśli jest mniejsza, wstawiamy opis „słabo”
- w drugim warunku sprawdzamy, czy wartość w kolumnie SalesYTD jest mniejsza równa 6 mln. Jeśli warunek jest spełniony wstawiamy opis „ok”
- w przypadku wierszy, które nie spełnią ani pierwszego, ani drugiego warunku wstawiamy opis „kosmiczna sprzedaż”
Grupowanie
Grupowanie danych polega na łączeniu wielu wierszy w jeden. Najprostszym przypadkiem grupowania jest połączenie wszystkich wierszy tabeli w jedną grupę i np. ich policzenie.
SELECT COUNT(*) FROM Person.Person;
Można też podzielić wiersze na grupy. Podstawą zakwalifikowania wiersza do danej grupy jest wartość jednej z kolumn lub wynik użytego do grupowania wyrażenia.
SELECT PersonType, COUNT(*) FROM Person.Person GROUP BY PersonType;
W przykładzie dzielimy wiersze na grupy według danych znajdujących się w kolumnie PersonType i zliczamy ile jest rekordów w każdej z grup.
Funkcje agregujące
Funkcje agregujące (grupujące) operują na zbiorach a nie na pojedynczych wartościach. Pozwalają one podsumowywać wyniki działania innych poleceń SQL, zliczać liczbę wystąpień, sumować, obliczać wartości średnie.
Zliczenie wierszy lub wartości w kolumnach – funkcja COUNT()
Funkcja COUNT() wywołana ze znakiem gwiazdki zlicza wszystkie rekordy przechowywane w tabeli włącznie z duplikatami i rekordami zawierającymi wartość specjalną NULL.
Zliczamy wszystkie rekordy
SELECT COUNT (*) FROM Person.Person;
Zliczamy wszystkie rekordy z wyjątkiem tych, które zawierają wartość specjalną NULL.
SELECT COUNT (LastName) FROM Person.Person;
Zliczamy unikalne rekordy – tylko te, które mają unikalne nazwiska (dane w kolumnie LastName).
SELECT COUNT (DISTINCT LastName) FROM Person.Person;
funkcja SUM() – zwrócenie sumy wartości w grupie
Argumentami funkcji SUM() mogą być tylko wartości numeryczne.
SELECT SUM(StandardCost) FROM Product;
funkcja AVG() – zwrócenie średniej wartości w grupie
Argumentami funkcji AVG() mogą być tylko wartości numeryczne.
SELECT AVG(StandardCost) FROM Product;
funkcja MIN() – zwrócenie najmniejszej wartości w grupie
Argumentami funkcji MIN() mogą być dane typu liczbowego, daty i czasu oraz tekstowe.
SELECT MIN(StandardCost) FROM Product;
funkcja MAX() – zwrócenie największej wartości w grupie
Argumentami funkcji MAX() mogą być dane typu liczbowego, daty i czasu oraz tekstowe.
SELECT MAX(StandardCost) FROM Product;
Klauzula GROUP BY
Klauzula GROUP BY umożliwia połączenie identycznych danych w grupy. Najczęściej wiersz jest klasyfikowany do danej grupy na podstawie wartości kolumny innej niż ta, dla której wywołana jest funkcja grupująca.
W poniższym zapytaniu funkcja grupująca wywołana jest dla kolumny Quantity natomiast wiersz jest klasyfikowany do grupy według kolumny ProductID.
SELECT ProductID, SUM(Quantity) FROM [Order Details] GROUP BY ProductID;
W klauzuli SELECT nie możemy umieszczać kolumn, które nie są wymienione w klauzuli GROUP BY.
SELECT ProductID, OrderID, SUM(Quantity) FROM [Order Details] GROUP BY ProductID, OrderID;
Filtrowanie grup – klauzula HAVING
Za pomocą klauzuli HAVING możesz ograniczyć liczbę wyświetlanych grup. Możesz umieścić w niej dowolną funkcję grupującą lub nazwy kolumn użytych do grupowania.
Umieszczony w klauzuli HAVING warunek logiczny jest sprawdzany dla każdej grupy i tylko te dane, dla których będzie on prawdziwy zostaną wybrane do wyniku zapytania.
SELECT ProductID, SUM(Quantity) FROM [Order Details] GROUP BY ProductID HAVING SUM(Quantity) > 1000;
W przykładzie wybieramy tylko te grupy, w których suma wyliczona dla grupy z danych w kolumnie Quantity wynosi więcej niż 1 tys.
Uwaga! Klauzula WHERE nakłada warunki na pojedyncze rekordy. Klauzula HAVING nakłada warunki na grupy rekordów tworzone przez klauzulę GROUP BY.
Więcej informacji na temat grupowania znajdziesz w artykule Grupowanie.
Złączenia tabel
Tabele możemy łączyć za pomocą operatora JOIN … ON.
W ramach operatora:
- wymieniamy nazwy wszystkich odczytywanych tabel
- określamy warunki ich łączenia
Złączenie wewnętrzne – JOIN
W wyniku złączenia wewnętrznego (INNER JOIN, JOIN) otrzymujemy tabelę wynikową, składającą się ze wszystkich kolumn tabel wejściowych. Zawierać ona będzie tylko te wiersze, dla których warunki złączenia będą spełnione (wynik będzie TRUE).
SELECT * FROM Customers a JOIN [Address] b ON a.CustomerID = b.CustomerID;
INNER JOIN jest złączeniem symetrycznym – nie ma znaczenia, w jakiej kolejności łączymy tabele A z B czy odwrotnie. Nie ma też znaczenia kolejność, w jakiej wypiszemy warunki złączenia w słowie kluczowym ON.
Jeżeli chcesz wyświetlić tylko niektóre kolumny, należy je wymienić w klauzuli SELECT.
Jeśli nazwa kolumny powtarza się w tabelach, które złączasz, aby ją wyświetlić należy jej nazwę poprzedzić nazwą tabeli lub aliasem nadanym dla tabeli.
W przykładzie łączymy tabelę Customers z tabelą Address. Do wykonania złączenia tabel używamy kolumny CustomerID. W wyniku otrzymamy tylko te rekordy, w których CustomerID jest takie samo w tabeli Customers i w tabeli Address.
Jeżeli tabele, które chcemy łączyć nie mają wspólnej kolumny musimy utworzyć złączenie na podstawie innej tabeli, która posiada wspólną kolumnę z jedną z łączonych tabel lub z obydwoma.
Aby połączyć tabelę A z tabelą C:
- Łączymy tabelę A z tabelą B według kolumny BusinessEntityID
- Łączymy tabelę B z tabelą C według kolumny AddressID
SELECT * FROM Person.Person A JOIN Person.BusinessEntityAddress B ON A.BusinessEntityID = B.BusinessEntityID JOIN Person.Address C ON B.AddressID = C.AddressID;
Złączenie zewnętrzne lewostronne – LEFT JOIN
W złączeniu zewnętrznym lewostronnym (LEFT OUTER JOIN, LEFT JOIN) łączone są najpierw wewnętrznie dwa zbiory (wykonywane jest złączenie wewnętrzne INNER JOIN), a na koniec dodawane są do wyniku wszystkie niedopasowane elementy tabeli po LEWEJ stronie operatora JOIN.
Wszystkie rekordy z tabeli po lewej stronie znajdą się w wyniku zapytania.
SELECT * FROM Customers a LEFT JOIN [Address] b ON a.CustomerID = b.CustomerID;
Złączenie zewnętrzne prawostronne – RIGHT JOIN
W złączeniu prawostronnym (RIGHT OUTER JOIN, RIGHT JOIN) łączone są najpierw wewnętrznie dwa zbiory (INNER JOIN), na koniec dodawane są do wyniku wszystkie niedopasowane elementy tabeli po PRAWEJ stronie operatora JOIN.
Wszystkie rekordy z tabeli po prawej stronie znajdą się w wyniku zapytania.
SELECT * FROM Customers a RIGHT JOIN [Address] b ON a.CustomerID = b.CustomerID;
Złączenie zewnętrzne obustronne – FULL JOIN
Złączenie zewnętrzne obustronne (FULL OUTER JOIN, FULL JOIN) zwraca wszystkie wiersze obu złączonych tabel, w tym te, które nie spełniają warunku złączenia
W wyniku znajdą się wszystkie rekordy z tabeli po prawej stronie oraz wszystkie rekordy z tabeli po lewej stronie.
SELECT * FROM Customers a FULL JOIN [Address] b ON a.CustomerID = b.CustomerID;
Iloczyn kartezjański
Zapytanie łączy każdy wiersz tabeli A z każdym wierszem tabeli B.
SELECT * FROM Customers a CROSS JOIN [Address] b;
Połączenie tabeli z samą sobą
Złączenie tabeli z samą sobą występuje, gdy po lewej i prawej stronie złączenia występuje ta sama tabela. Konieczne jest w nim użycie aliasów.
Ma zastosowanie, jeżeli chcemy porównać wybrane rekordy tabeli z innymi rekordami tej samej tabeli.
SELECT a.BusinessEntityID, a.FirstName, a.LastName, b.FirstName, b.LastName FROM Person.Person a, Person.Person b WHERE a.BusinessEntityID > b.BusinessEntityID AND a.FirstName = b.FirstName;
Złączenia wielokrotne
W jednym zapytaniu możemy odwołać się do wielu tabel. Jednak z każdą następną dołączoną tabelą spada wydajność zapytania. Aby zoptymalizować zapytanie można stworzyć tabele tymczasowe.
Wynik złączenia
Jeśli mamy możliwość, przy złączeniach wielokrotnych każdą kolejną tabelę powinniśmy dołączać do pierwszej tabeli.
W przykładzie tabelę Orders możemy dołączyć do tabeli Address lub do tabeli Customers. Lepiej jest dołączyć tabelę Orders do Customers, gdyż w tabeli Customers są wszystkie rekordy. W tabeli Address nie ma rekordu z CustomerID nr 7. Gdybyśmy dołączyli Orders do Address, zamówienia dla rekordu CustomerID nr 7 nie zostałyby wyświetlone.
Więcej informacji na temat łączenia tabel znajdziesz w artykule Złączenia tabel
Łączenie wyników zapytań
Oprócz łączenia tabel, język SQL pozwala także łączyć wyniki zapytań. Łączenie wyników zapytań to dodawanie lub usuwanie wierszy zwróconych przez złączone zapytania.
Łączone wyniki zapytań muszą składać się z tej samej liczby kolumn. Dane w odpowiadających sobie kolumnach muszą być tego samego typu albo umożliwiać niejawną konwersję typów.
Operator UNION
Za jego pomocą możemy dodać do siebie wyniki zapytań. Operator UNION powoduje usunięcie z wyniku powtórzonych wierszy.
SELECT * FROM Customers UNION SELECT * FROM Employees
Operator UNION ALL
Za jego pomocą możemy złączyć ze sobą wyniki zapytań bez eliminowania duplikatów.
SELECT * FROM Customers UNION SELECT * FROM Employees
Operator INTERSECT
Zwraca część wspólną wyników dwóch zapytań, a więc tylko te wiersze, które zostały zwrócone przez obydwa zapytania.
SELECT * FROM Customers INTERSECT SELECT * FROM Employees
Operator EXCEPT
Zwraca te wiersze, które znalazły się wyłączenie w wyniku pierwszego zapytania i nie było ich w wyniku drugiego zapytania.
SELECT * FROM Customers EXCEPT SELECT * FROM Employees
Więcej informacji na temat łączenia wyników zapytań znajdziesz w artykule Łączenie wyników zapytań.
Wszystkie klauzule opisane w artykule przećwiczysz na naszym kursie SQL poziom podstawowy. Przygotowaliśmy ponad 100 ćwiczeń. Zapraszamy.