Podzapytania i złączenia.

Transkrypt

Podzapytania i złączenia.
3.
Podzapytania, łączenie tabel i zapytań
I.
PODZAPYTANIE (SUBSELECT)
oddzielna, ujęta w nawiasy instrukcja SELECT,
zagnieżdżona w innej instrukcji SQL, zazwyczaj w instrukcji SELECT
w instrukcji SELECT, podzapytanie może być umieszczone w klauzuli:
o
WHERE, HAVING (jako część warunku logicznego)
o
SELECT (podzapytanie musi wówczas zwracać dokładnie jedną wartość)
o
FROM (pełni rolę źródła danych)
o
ORDER BY (musi zwracać dokładnie jedną wartość)
o
Firebird umożliwia także umieszczanie podzapytań w klauzuli GROUP BY (takie podzapytanie musi
zwracać dokładnie jedną wartość)
a. PODZAPYTANIA PROSTE
• podzapytanie proste jest wykonywane jako pierwsze, jego wynik jest zapamiętany i przekazany do
zewnętrznego zapytania (podzapytania można zagnieżdżać wielokrotnie)
• jako wynik zazwyczaj zwraca tabelę jednokolumnową (wyjątkiem jest wykorzystanie operatora EXISTS lub
SINGULAR lub umieszczenie podzapytania w klauzuli FROM)
8
• podzapytanie proste w klauzuli WHERE lub HAVING
SELECT lista wyrażeń FROM lista tabel
WHERE wyrażenie operator (SELECT wyrażenie FROM ...)
SELECT lista wyrażeń FROM lista tabel
GROUP BY lista wyrażeń
HAVING wyrażenie operator (SELECT wyrażenie FROM ...)
• możliwe operatory:
operator relacji (<, >, =, !=, <>,<=,>=), jeżeli podzapytanie zwraca dokładnie jedną wartość
operator relacji (<, >, =, !=, <>,<=,>=), w połączeniu z jednym z poniższych słów kluczowych, jeżeli
podzapytanie zwraca wiele wartości (lub może zwrócić wiele wartości):
ANY – warunek jest spełniony, gdy wartość zwrócona przez podzapytanie jest w relacji z przynajmniej
jedną z wartości podzapytania
ALL – gdy wartość jest w relacji ze wszystkimi wartościami zwróconymi przez podzapytanie
IN / NOT IN
BETWEEN / NOT BETWEEN
9
b. PODZAPYTANIA SKORELOWANE – wartość z zapytania zewnętrznego jest przekazywana jako parametr
do podzapytania, które posiada (najczęściej) w klauzuli WHERE warunek skorelowania określający, jak
mają być połączone podzapytanie z zapytaniem zewnętrznym;
często wymaga użycia aliasów nazw tabel, aby odróżnić kolumny z podzapytania i zapytania głównego;
podzapytanie jest wykonywane dla każdego wiersza zapytania głównego – wartość podzapytania jest
wyznaczana na podstawie wartości parametru pobranego z zapytania zewnętrznego;
podzapytanie skorelowane w klauzuli WHERE lub HAVING:
wynik zwrócony przez podzapytanie pozwala określić, jaki ostatecznie zbiór rekordów zwróci zapytanie
zewnętrzne;
w podzapytaniu skorelowanym często wykorzystuje się:
predykat EXISTS - przyjmuje wartość prawdy, gdy podzapytanie zwróci przynajmniej jeden wiersz
predykat SINGULAR – przyjmuje wartość prawdy, gdy podzapytanie zwróci dokładnie jeden wiersz
jeżeli używamy EXISTS lub SINGULAR, to podzapytanie może zwracać cały wiersz danych
SELECT full_name, salary, dept_no
SELECT COUNT(*) FROM employee e
FROM employee e1
WHERE EXISTS(SELECT * FROM department d
WHERE salary=
WHERE mngr_no IS NULL
(SELECT MAX(salary) FROM employee e2
AND d.dept_no=e.dept_no)
WHERE e1.dept_no=e2.dept_no)
10
c) PODZAPYTANIA w klauzuli SELECT
Podzapytanie umieszczeno w klauzuli SELECT musi zwracać dokładnie jedną wartość. Często jest to
podzapytanie skorelowane.
SELECT full_name, salary, (SELECT AVG(salary)
SELECT full_name as pracownik,
FROM employee)
(SELECT full_name FROM employee
FROM employee
WHERE emp_no=(SELECT mngr_no
WHERE dept_no=’600’
FROM department d
WHERE d.dept_no=e.dept_no) )
as szef
FROM employee e
WHERE e.full_name=’Nelson, Robert’
d) PODZAPYTANIA w klauzuli FROM
Podzapytanie zwraca zestaw rekordów, który jest źródłem danych dla zapytania zewnętrznego.
Aby odwołać się do kolumn z podzapytania, należy nadać aliasy kolumnom lub nadać alias całej „tabeli”
zwróconej przez podzapytanie.
SELECT ile, dept_no
FROM (SELECT count(*) as ile, dept_no FROM employee GROUP BY dept_no)
11
WHERE ile <=3
SELECT MAX(ile)
FROM (SELECT count(*) as ile FROM employee GROUP BY dept_no)
d) PODZAPYTANIA w klauzuli ORDER BY
umożliwiają sortowanie zgodnie z wartościami zwróconymi przez podzapytanie (dla jednego wiersza zapytania
głównego powinna być tylko jedna wartość zwrócona przez podzapytanie)
SELECT dept_no, full_name, (SELECT count(*) FROM employee e2 WHERE e1.dept_no=e2.dept_no)
FROM employee e1
ORDER BY (SELECT count(*) FROM employee e2 WHERE e1.dept_no=e2.dept_no)
lub
SELECT dept_no, full_name, (SELECT count(*) FROM employee e2 WHERE e1.dept_no=e2.dept_no)
FROM employee e1
ORDER BY 3
12
ZŁĄCZENIA TABEL
• łączenie tabel używane jest z reguły w celu wyboru danych z więcej niż jednej tabeli
1. złączenie krzyżowe - jeżeli wymienimy więcej niż jedną tabelę we frazie FROM, utworzony zostanie
iloczyn kartezjański
SELECT ... FROM tabela1, tabela2,...
2. złączenie wewnętrzne – należy określić warunek złączenia, w klauzuli WHERE lub za pomocą frazy JOIN
• SELECT ... FROM tabela1, tabela2
WHERE tabela1.kol_a = tabela2.kol_b
• SELECT ... FROM tabela1 JOIN tabela2
ON (tabela1.kol_a = tabela2.kol_b)
w warunku złączenia najczęściej wykorzystuje się istniejące w schemacie danej bazy związki klucza
głównego z kluczem obcych w tabelach, które chcemy złączyć
SELECT full_name, department
FROM employee e, department d
WHERE e.dept_no=d.dept_no
//warunek złączenia
złączenia wewnętrzne pozwalają wybierać dane tylko z tych wierszy, które mają odpowiadające im wiersze
w obu tabelach – nie uwzględniają możliwości wystąpienia NULL
13
można łączyć więcej niż dwie tabele (należy wówczas podać odpowiednie warunki złączenia, np. aby
połączyć trzy tabele, należy podać dwa warunki złączenia, itp.)
SELECT
full_name, department, job_title
FROM
(employee e JOIN department d ON (e.dept_no=d.dept_no))
JOIN job j ON (e.job_code=j.job_code)
• jest możliwe samozłączenie, czyli łączenie ze sobą tej samej tabeli – trzeba wówczas stosować aliasy, aby
rozróżnić dwie kopie danej tabeli
SELECT e1.full_name, e1.job_country
FROM employee e1 JOIN employee e2 ON(e1.job_country=e2.job_country)
WHERE e2.emp_no=2
• najczęściej złączeń dokonuje się według atrybutów kluczowych, ewentualnie kolumn o unikalnych
wartościach;
• warunek złączenia może być oparty o więcej, niż jedną kolumnę;
• możliwe jest też łączenie tabel wg innych kryteriów, niż równość, np.
SELECT e1.full_name, e1.salary
FROM employee e1 JOIN employee e2 ON(e1.salary>e2.salary)
WHERE e2.emp_no=2
14
3. złączenie zewnętrzne – tworzymy za pomocą klauzuli FULL/LEFT/RIGHT JOIN
złączenia zewnętrzne są używane, gdy w jednej z tabel w polu łączenia pojawia się NULL,
istniejące wiersze z jednej tabeli są wówczas łączone z pustymi wierszami
LEFT JOIN (RIGHT JOIN) – lewe (prawe) złączenie zewnętrzne, używamy, gdy chcemy uwzględnić
wszystkie wiersze z tabeli stojącej po lewej (prawej) stronie JOIN, w sytuacji, gdy w tabeli stojącej
po prawej (lewej) stronie JOIN może nie być odpowiedników dla wszystkich wierszy z tabeli z lewej
(prawej) strony, np. zapytanie ze złączeniem wewnętrznym
SELECT d.department, d.budget, e.full_name, e.salary
FROM department d JOIN employee e ON(d.dept_no=e.dept_no)
uwzględnia tylko te działy, które mają co najmniej jednego pracownika. Jeżeli chcemy uwzględnić
wszystkie działy w zestawieniu, to musimy użyć złączenia zewnętrznego, np. lewe złączenie
zewnętrzne:
SELECT d.department, d.budget, e.full_name, e.salary
FROM department d LEFT JOIN employee e
(lewa tabela)
ON (d.dept_no=e.dept_no)
(prawa tabela)
pełne złączenie zewnętrzne FULL JOIN:
SELECT d.department, d.budget, e.full_name, e.salary
FROM department d FULL JOIN employee e
15
ON (d.mngr_no=e.emp_no)

Podobne dokumenty