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)