Plan! Podzapytania (subqueries)! Podzapytania do tabel! Podzapytanie jako wyrażenie! Podzapytania skorelowane! operatory IN, NOT IN! operatory EXISTS, NOT EXISTS
sales,fk1 stor_id ord_num,fk2,i1 title_id ord_date qty payterms employee em p_id I1 fname I1 minit I1 lname FK1 job_id job_lvl FK2 pub_id hire_date stores stor_id stor_name stor_address city state zip jobs job_id job_desc min_lvl max_lvl titleauthor,fk1,i1 au_id,fk2,i2 title_id au_ord royaltyper pub_info,fk1 pub_id logo pr_info authors au_id I1 au_lnam e I1 au_fnam e phone address city state zip contract titles title_id I1 title type FK1 pub_id price advance royalty ytd_sales notes pubdate publishers pub_id pub_name city state country roysched FK1,I1 title_id lorange hirange royalty discounts discounttype FK1 stor_id low qty highqty discount Pubs Database Diagram
Podzapytania do tabel! W miejscu w którym możemy użyć nazwy tabeli, możemy użyć podzapytania USE northwind SELECT T.orderid, T.customerid FROM ( SELECT orderid, customerid FROM orders ) AS T
Podzapytanie jako wyrażenie! Podzapytanie zwraca pojedynczą wartość! Podzapytanie może być traktowane jako wyrażenie " może pojawić się na liście polecenia select USE pubs SELECT title, price,( SELECT AVG(price) FROM titles) AS average,price-(select AVG(price) FROM titles) AS difference FROM titles WHERE type='popular_comp'! UWAGA: Podzapytanie jest wykowane tylko raz
Podzapytania skorelowane Zewnętrzne zapytanie przekazuje dane dane do do zapytania wenętrznego Zapytanie wewnętrzne wykorzystuje USE northwind te te dane dane od od wygenerowania SELECT orderid, customerid wyniku FROM orders AS or1 WHERE 20 < (SELECT quantity FROM [order details] AS od WHERE or1.orderid = od.orderid AND od.productid = 23) Zapytanie wewnętrzne zwraca zwraca ten ten wynik wynik do do zapytania zewnętrznego Proces Proces jest jest powtarzany dla dla każdego wiersza zapytania wewnętrznego Back to to Step 1
Podzapytania skorelowane! Dla każdego produktu podaj maksymalną liczbę zamówionych jednostek USE northwind SELECT DISTINCT productid, quantity FROM [order details] AS ord1 WHERE quantity = ( SELECT MAX(quantity) FROM [order details] AS ord2 WHERE ord1.productid = ord2.productid ) ORDER BY productid
To samo przy użyciu GROUP BY! Dla każdego produktu podaj maksymalną liczbę zamówionych jednostek select productid, max(quantity) from [order details] group by productid order by productid
Przykład! Podaj typy książek publikowane przez więcej niż jednego wydawcę USE pubs SELECT DISTINCT t1.type FROM titles AS t1 WHERE t1.type IN (SELECT t2.type FROM titles AS t2 WHERE t1.pub_id <> t2.pub_id)
Podzapytania vs złączenia! podzapytanie USE pubs SELECT DISTINCT t1.type FROM titles AS t1 WHERE t1.type IN (SELECT t2.type FROM titles AS t2 WHERE t1.pub_id <> t2.pub_id)! złączenie USE pubs SELECT DISTINCT t1.type FROM titles AS t1 INNER JOIN titles AS t2 ON t1.type = t2.type WHERE t1.pub_id <> t2.pub_id
Przykład! Podaj wszystkie tytuły których cena jest większa niż średnia cena ks~iążek tego samego typu
Podzapytania vs HAVING! podzapytanie USE pubs SELECT t1.type, t1.title, t1.price FROM titles AS t1 WHERE t1.price > ( SELECT AVG(t2.price) FROM titles AS t2 WHERE t1.type = t2.type )! to samo przy użyciu grupowania i operatora HAVING USE pubs SELECT t1.type, t1.title, t1.price FROM titles AS t1 INNER JOIN titles AS t2 ON t1.type = t2.type GROUP BY t1.type, t1.title, t1.price HAVING t1.price > AVG(t2.price)
Operatory EXISTS, NOT EXISTS! Zewnętrzne zapytanie testuje wystąpienie (lub nie) zbioru wynikowego określonego przez zapytanie wewnętrzne " zapytanie wewnętrzne zwraca TRUE lub FALSE USE northwind SELECT lastname, employeeid FROM employees AS e WHERE EXISTS (SELECT * FROM orders AS o WHERE e.employeeid = o.employeeid AND o.orderdate = '9/5/97')! Zapytanie zwraca listę wszystkich pracowników którzy złożyli obsłużyli zamówienie '9/5/97'
EXISTS vs JOIN! podzapytanie USE northwind SELECT lastname, employeeid FROM employees AS e WHERE EXISTS (SELECT * FROM orders AS o WHERE e.employeeid = o.employeeid AND o.orderdate = '9/5/97')! join USE northwind SELECT DISTINCT lastname, e.employeeid FROM orders AS o INNER JOIN employees AS e ON o.employeeid = e.employeeid WHERE o.orderdate = '9/5/1997'