09. Podzapytania.txt

(46 KB) Pobierz
#189
Rozdział 9.
Podzapytania

W niektórych wypadkach najprostszš metodš osišgnięcia jakiego celu w języku SQL jest wykorzystanie wyniku jednego zapytania w drugim. Zagnieżdżone zapytania, nazywane również podzapytaniami, mogš być używane w klauzuli WHERE do filtrowania danych lub w instrukcji INSERT do kopiowania danych z jednej tabeli do drugiej.
Podzapytań używamy, gdy dane z pewnej tabeli sš potrzebne w innym zapytaniu. Podobnie jak możemy zagnieżdżać wywołania funkcji w innych funkcjach, tak samo możemy zagnieżdżać zapytania w innych zapytaniach. Wykorzystujšc podzapytania można osišgnšć podobny efekt, jaki osišgamy przez wprowadzenie zmiennych w proceduralnych językach programowania. Zamiast wykonania instrukcji i przechowania j ej w zmiennej, wykonywane jest drugie wyrażenie wykorzystujšce poprzedni wynik, co daje efekt zagnieżdżania pierwszej instrukcji w drugiej.
Podzapytania sš złożonš kwestiš z kilku powodów. Po pierwsze, wyróżniamy dwa zasadniczo różnišce się typy podzapytań. Po drugie, podzapytania mogš być wykorzystane w kilku typach instrukcji języka SQL. Po trzecie, wykorzystanie podzapytań zależy od typów danych zwracanych przez te zapytania. Przed zagłębieniem się w tematykę podzapytań, wypadałoby jeszcze dodać, że częć możliwoci podzapytań może być zastšpiona przez zapytania złšczajšce. Gdziekolwiek w tym rozdziale wprowadzę nowy typ podzapytania, pokażę również, jak je zastšpić (jeli to możliwe) przez złšczenie. Za każdym razem kiedy będzie to możliwe pokażę alternatywne wykorzystanie zapytań złšczajšcych, choć w przypadku najbardziej przydatnych podzapytań, nie ma możliwoci zastšpienia ich innymi metodami.
==================
Rada
Ze względu na uproszczenie przykładowej bazy danych, dane, którymi dysponuję, nie zawsze pozwalajš mi zademonstrować podzapytania w taki sposób, żeby pokazać, że jest to najlepsza metoda wyszukania odpowiednich danych. Mimo to wyjanię sytuacje, w których podzapytania sš najbardziej odpowiedniš technikš wyszukania potrzebnych danych.
=====================
#190
Co to jest podzapytanie?

Podzapytanie to, najprociej mówišc, instrukcja SELECT zagnieżdżona w innej instrukcji SQL, która dostarcza dla tej drugiej danych wejciowych. Podczas dyskusji o podzapytaniach będę odwoływał się do zapytań zewnętrznych jako otaczajšcych podzapytanie.
Podzapytanie jest zapytaniem zagnieżdżonym. Zapytanie otaczajšce też może być podzapytaniem, ponieważ SQL nie wprowadza ograniczeń na iloć zagnieżdżeń. Jeli zapytanie jest podzapytaniem, to kolejne zapytanie może pojawić się w jego klauzuli WHERE.
=================
Rada
Niektórzy ludzie okrelajš zapytanie otaczajšce jako zapytanie zewnętrzne, a zapytanie zagnieżdżone jako wewnętrzne.
================

Rozpocznijmy od przykładu. Listing 9.1 zawiera przykład prezentowany już w rozdziale 6. "Zastosowanie klauzuli WHERE", gdzie wspomniałem, że podzapytania często pojawiajš się łšcznie z wyrażeniem IN.
---------------------------
Listing 9.1. Podzapytanie w wyrażeniu IN

SELECT movie_title,   dlrector_id
FROM Movies
WHERE director_ld IN(
SELECT person_id
FROM People                                                                                             WHERE person_state = 'TX'
)
MOVIE_TITLE		STUDIO_ID
---------------------------
Prince Kong		2
Hard Code		4
---------------------------

Zapytanie wewnętrzne na listingu 9.1 dostarcza listę wartoci z pola person_id do wyrażenia IN w zapytaniu otaczajšcym. Gdyby nie istniały podzapytania, to zapy-      tanie musiałoby być zastšpione przez dwa oddzielne zapytania, jak pokazano na listingu 9.2 i 9.3.                                        ---------------------------
Listing 9.2. Pobranie listy osób z Teksasu

SELECT  person_id
FROM  People
WHERE  person_state = 'TX'

PERSON_ID
-------------
4
5
6
10
---------------------------
#191
---------------------------
Listing 9.3. Wyszukanie listy filmów reżyserowanych przez osoby zamieszkałe w stanie Teksas

SELECT movie_title, director_id
FROM Movies
WHERE director id IN(4, 5, 6,10)

MOVIE_TITLE		STUDIO_ID
---------------------------
Prince Kong		2
Hard Code		4
---------------------------

Jeli nie zastosujemy podzapytania, to dane zwrócone przez zapytanie z listingu 9.2 muszš być wprowadzone do zapytania z listingu 9.3. Jak widać, możliwoć zagnieżdżania zapytań znacznie ułatwia uzyskiwanie potrzebnych informacji za pomocš tylko jednego zapytania.

Zastępowanie podzapytań przez złšczenia

Zapytanie z listingu 9. l może być również zastšpione przez złšczenie, jak pokazano na listingu 9.4.
---------------------------
Listing 9.4. Złšczenie zastępujšce podzapytanie

SELECT movie_title,   studio_id
FROM Movies, People
WHERE diredctor_id=person_id
AND person_state='TX'
                                                                                        MOVIE_TITLE		STUDIO_ID
---------------------------
Prince Kong		2
Hard Code		4
---------------------------

Wyniki zapytań z listingów 9.4 i 9.1 sš identyczne. Nie ma żadnej przyczyny, dla której jedno z nich można by uznać za lepsze od drugiego. Sš porównywalne zarówno ze względu na wydajnoć jak i na wyniki. Wybór metody zależy od naszych upodobań.

Typy podzapytań

Wyróżniamy dwa typy podzapytań: powišzane i niepowišzane. Podzapytanie powišzane wymaga danych z zapytania otaczajšcego, zanim może być wykonane. Podzapytanie wykonuje się wykorzystujšc dane z zapytania otaczajšcego, a dane przez nie zwrócone sš z powrotem wprowadzane do zapytania otaczajšcego. Podzapytanie niepowišzane wykonuje się przed zapytaniem otaczajšcym, a jego wyniki sš przekazywane do zapytania otaczajšcego. Podzapytanie niepowišzane jest prostszym przykładem podzapytań, choć niekoniecznie częciej używanym.
Podzapytania mogš być również wykorzystane w instrukcjach INSERT, aby dostarczyć wiersze z wartociami, które maja być wprowadzone do tabeli. Ponadto, podzapytania mogš być wykorzystane przez instrukcje UPDATE i DELETE do utworzenia złożonych warunków, niemożliwych do sformułowania za pomocš złšczeń.
#192
Podzapytania niepowišzane

Zapytanie wykorzystujšce niepowišzane podzapytanie, wykonuje zagnieżdżone zapytanie, wprowadza dane do zapytania otaczajšcego i wykonuje je. Podzapytanie niepowišzane można poznać po tym, że nie zawiera żadnych odwołań do zapytania otaczajšcego. Listing 9.1 zawiera przykład takiego powišzania. Poniżej przedstawiono ogólnš składnię takiego zapytania:

SELECT select_listopad
FROM table [ , table ...]..
WHERE column_name IN                                                                                        (SELECT [DISTINC] column FROM table
[WHERE condition])

Podzapytania niepowišzane mogš być pisane na wiele sposobów, ale najpopularniejsze jest użycie klauzuli IN.
Na listingu 9.1 podzapytanie wybiera listę identyfikatorów z tabeli People, która jest wykorzystana jako lista wartoci w klauzuli IN. Takie zapytanie jest okrelane jako niepowišzane, ponieważ w żaden sposób nie zależy od otaczajšcego je zapytania.. Podzapytanie jest wykonywane, a wyniki sš porównywane z wartociami z tabeli okrelonej w zapytaniu otaczajšcym. Jak niedługo wyjanię, podzapytanie powišzane wykorzystuje dane wybrane przez zapytanie otaczajšce i dostarcza wyniki oparte na tych danych.

Podzapytanie powišzane

Zapytanie powišzane różni się od zapytania niepowišzanego tym, że pozycje z listy SELECT zapytania otaczajšcego sš wykorzystane wewnštrz klauzuli WHERE podza-pytania. Najprociej wyjanić to na przykładzie.
Zapytanie powišzane przypomina złšczenia, ponieważ zawartoć tabeli występujšcej w podzapytaniu będzie porównywana z zawartociš tabeli z zapytania otaczajšcego, podobnie jak w zapytaniu złšczajšcym.
Różnica polega na tym, że zamiast warunku złšczajšcego, powišzane podzapytanie odwołuje się do zapytania zewnętrznego przez klauzulę WHERE zapytania wewnętrznego. Ilustruje to listing 9.5.
---------------------------
Listing 9.5. Powišzane podzapytanie

SELECT person_fname, person_lname
FROM People Pl
WHERE 'Pam Green1 IN (
Select ROLE
FROM Cast_movies
WHERE Pl.person_id = cast_member_id)

PERSON_FNAME     PERSON_LNAME
---------------------------
Carol		Delano
---------------------------
#193
Przedstawione zapytanie przetwarza każdy wiersz z tabeli People następujšco:
1. Zawartoć wiersza jest odczytywana z bazy danych.
2.  Wykonuje się podzapytanie, a wartoci z aktualnie wybranego wiersza zapytania otaczajšcego sš wykorzystywane w klauzuli WHERE podzapytania.
3.  Wyniki podzapytania sš przekazywane do klauzuli WHERE.
4.  W przypadku, gdy wyrażenie logiczne w warunku klauzuli WHERE ma wartoć prawda, wiersz jest pobierany do zestawienia wynikowego, w przeciwnym wypadku jest pomijany.
Funkcje zapytania z listingu 9.5 można zastšpić zapytaniem złšczajšcym, jak pokazuje to listing 9.6.
---------------------------
Listing 9.6. Zapytanie złšczajšce zastępujšce poprzednie zapytanie

SELECT person_fname, person_lname
FROM People, Cast_Movies
WHERE 'cast_member_id=person_id
AND role ='Pam Green'

PERSON_FNAME	PERSON_LNAME
---------------------------
Carol		Delano
---------------------------

Zdarzajš się również zadania, jak pokażę póniej, które mogš być zrealizowane tylko przez podzapytania.

Podzapytania zwracajšce listę wartoci

Podzapytania mogš być wykorzystywane w dwóch różnych kontekstach: kiedy wymagana jest pojedyncza wartoć lub kiedy wymagana jest lista wartoci. W przypadku, gdy wymagana jest lista wartoci, podzapytanie może zwrócić dowolnš liczbę wartoci (włšczajšc 0), zapewniajšc poprawne działanie zapytania.
=================
Uwaga
Podzapytanie użyte wewnštrz klauzuli WHERE musi zawsze zwrócić wartoci z jednej kolumny. Jeli wybierzemy wiele kolumn, pojawi się komunikat o błędzie.
===========...
Zgłoś jeśli naruszono regulamin