MySQL Podzapytanie z przykładami

⚡ Inteligentne podsumowanie

MySQL Składnia podzapytania umieszcza jedno polecenie SELECT w drugim, więc wynik wewnętrzny zasila zapytanie zewnętrzne. To wyjaśnienie obejmuje podzapytania skalarne, wierszowe i tabelaryczne, kolejność wykonywania, praktyczne przykłady oraz kompromis wydajnościowy w porównaniu z operacjami JOIN.

  • 🔍 Definicja podstawowa: Podzapytanie to polecenie SELECT zagnieżdżone w innym zapytaniu, przy czym najpierw uruchamiane jest zapytanie wewnętrzne w celu dostarczenia wartości zapytaniu zewnętrznemu.
  • 🧮 Podzapytanie skalarne: Zwraca pojedynczy wiersz i jedną kolumnę, dlatego można go łączyć z operatorami porównania, takimi jak równa się, większe niż lub mniejsze niż.
  • 📋 Podzapytania wierszowe i tabelaryczne: Podzapytanie wierszowe zwraca jeden wiersz z kilkoma kolumnami, natomiast podzapytanie tabelowe zwraca wiele wierszy i działa z operatorem IN.
  • 🧩 Głębokość zagnieżdżenia: Podzapytania mogą być zagnieżdżone na kilka poziomów, co pozwala na umieszczanie wartości, takich jak element o najwyższej wartości, w jednym poleceniu.
  • ✍️. Poza SELECT: Polecenia INSERT, UPDATE i DELETE akceptują podzapytania, co umożliwia wprowadzanie zmian zbiorczych bez konieczności stosowania tabel tymczasowych.
  • Zasada wydajności: Połączenie JOIN zazwyczaj działa znacznie szybciej niż odpowiadające mu podzapytanie, dlatego podzapytania należy przeznaczyć na logikę, której połączenie JOIN nie jest w stanie wyrazić.

MySQL Podzapytanie

Czym jest podzapytanie w SQL?

A podzapytanie to zapytanie SELECT zawarte w innym zapytaniu. Wewnętrzne zapytanie SELECT jest zazwyczaj używane do określania wyników zewnętrznego zapytania SELECT, dlatego baza danych najpierw ocenia instrukcję wewnętrzną, a następnie przekazuje jej wynik do góry.

Wewnętrzne zapytanie nazywa się wewnętrzne zapytanie lub zagnieżdżone zapytanie, a polecenie, które je zawiera, nazywa się zapytanie zewnętrznePrzyjrzyjmy się składni podzapytania.

MySQL Podzapytanie

Powyższy diagram przedstawia ogólną formę instrukcji: zewnętrzne polecenie SELECT zwraca kolumny, które chcesz wyświetlić, a wewnętrzne polecenie SELECT w nawiasach kwadratowych zwraca wartość lub listę wartości, z którymi porównuje się klauzula WHERE.

Dlaczego warto używać podzapytania?

Zanim przyjrzymy się różnym typom, warto wiedzieć, kiedy podzapytanie zdobywa swoje miejsce w poleceniu.

Podzapytanie odpowiada na pytanie, którego wartość filtru nie jest znana z góry. Musi zostać obliczona na podstawie samych danych. Częstą skargą klientów w bibliotece wideo MyFlix jest mała liczba tytułów filmowych, a kierownictwo chce kupować filmy z kategorii o najmniejszej liczbie tytułów. Nikt nie wie, o którą kategorię chodzi, dopóki baza danych nie zostanie zapytana, więc wartość musi zostać najpierw obliczona, a następnie użyta jako filtr.

Podzapytania są wtrackorzystne z trzech praktycznych powodów:

  • Czytelność: Każda część logiki znajduje się w osobnym bloku w nawiasach, dzięki czemu oświadczenie można odczytać jako sekwencję małych pytań, a nie jako jedno złożone wyrażenie.
  • Izolacja: Można uruchomić niezależne zapytanie wewnętrzne, aby potwierdzić, że zwraca ono oczekiwaną wartość, co znacznie ułatwia testowanie i debugowanie.
  • Elastyczność: Ten sam schemat działa w klauzulach WHERE, HAVING, SELECT i FROM, a także wewnątrz poleceń INSERT, UPDATE i DELETE.

Kompromisem jest szybkość, która zostanie omówiona w porównaniu JOIN w dalszej części artykułu.

Typy podzapytań w MySQL

MySQL Obsługuje trzy typy podzapytań, a typ jest określany na podstawie kształtu wyniku zwracanego przez zapytanie wewnętrzne. Każdy typ jest wyjaśniony poniżej wraz z działającym przykładem w bazie danych myflixdb.

1) Podzapytanie skalarne

A podzapytanie skalarne Zwraca dokładnie jeden wiersz i jedną kolumnę, co oznacza, że ​​zwraca pojedynczą wartość. Ponieważ wynik jest pojedynczą wartością, można go użyć wszędzie tam, gdzie dozwolona jest wartość literałowa. Wracając do powyższego problemu MyFlix, możesz użyć zapytania takiego jak to:

SELECT category_name FROM categories
WHERE category_id = (SELECT MIN(category_id) FROM movies);

Daje to wynik:

MySQL Podzapytanie

Zobaczmy jak działa to zapytanie.

MySQL Podzapytanie

Jak pokazuje diagram wykonania, MySQL pierwsze biegi SELECT MIN(category_id) FROM movies, otrzymuje jedną wartość i dopiero wtedy uruchamia zapytanie zewnętrzne z tą wartością. Ponieważ zwracana jest jedna wartość, dozwolone operatory to standardowy zestaw porównań: =, <> (lub !=), >, >=, <, <=.

💡 Wskazówka: Jeśli podzapytanie umieszczone po = zwraca więcej niż jeden wiersz, MySQL podnosi błąd 1242, Podzapytanie zwraca więcej niż 1 wierszPrzełącz operatora na INlub zawęż wewnętrzną klauzulę WHERE.

2) Podzapytanie wierszowe

A podzapytanie wierszowe Zwraca również pojedynczy wiersz, ale wiersz ten może zawierać więcej niż jedną kolumnę. Zapytanie zewnętrzne porównuje zatem wiersz wartości z konstruktorem wiersza, a nie z pojedynczą wartością.

SELECT full_names, contact_number FROM members
WHERE (membership_number, gender) = (SELECT membership_number, gender FROM members WHERE full_names = 'Janet Jones');

Dopuszczalne operatory to takie same operatory porównania, jak te wymienione powyżej, stosowane jednocześnie do całego wiersza.

3) Podzapytanie tabeli

A podzapytanie tabeli zwraca wiele wierszy, a często także wiele kolumn, dlatego zapytanie zewnętrzne musi używać operatora zbiorów, takiego jak IN, NOT IN, ANY, ALLlub EXISTS.

Załóżmy, że chcesz poznać nazwiska i numery telefonów osób, które wypożyczyły film i jeszcze go nie zwróciły, aby móc do nich zadzwonić i przywołać przypomnienie. Możesz użyć zapytania takiego jak to:

SELECT full_names, contact_number FROM members
WHERE membership_number IN (SELECT membership_number FROM movierentals WHERE return_date IS NULL);

MySQL Podzapytanie

Zobaczmy jak działa to zapytanie.

MySQL Podzapytanie

W tym przypadku zapytanie wewnętrzne zwraca więcej niż jeden wynik, więc lista numerów członkostwa jest przekazywana do IN operator i zwracany jest każdy pasujący element.

Zagnieżdżanie podzapytań na kilku poziomach głębokości

Do tej pory widziałeś dwa poziomy. Podzapytanie może również zawierać inne podzapytanie, które generuje potrójnie zagnieżdżone polecenie.

Załóżmy, że zarząd chce nagrodzić najlepiej płacącego członka. Możemy uruchomić takie zapytanie:

SELECT full_names FROM members
WHERE membership_number = (SELECT membership_number FROM payments
    WHERE amount_paid = (SELECT MAX(amount_paid) FROM payments));

Zapytanie najbardziej wewnętrzne znajduje największą płatność, zapytanie środkowe konwertuje tę kwotę na numer członkostwa, a zapytanie zewnętrzne konwertuje numer członkostwa na nazwę. Powyższe zapytanie daje następujący wynik:

MySQL Podzapytanie

Jak używać podzapytań z poleceniami INSERT, UPDATE i DELETE

Podzapytania nie ograniczają się do instrukcji SELECT. Ten sam schemat w nawiasach działa wewnątrz instrukcji modyfikacji danych, co pozwala na zmianę całego zestawu wierszy w jednym przebiegu bez tworzenia tabeli tymczasowej.

INSERT z podzapytaniem. Podzapytanie może dostarczyć wstawianych wierszy, co powoduje skopiowanie danych z jednej tabeli do drugiej. Lista kolumn instrukcji SELECT musi być zgodna z listą kolumn instrukcji INSERT.

INSERT INTO vip_members (membership_number, full_names)
SELECT membership_number, full_names FROM members
WHERE membership_number IN (SELECT membership_number FROM payments WHERE amount_paid > 5000);

UPDATE z podzapytaniem. W tym przypadku zapytanie wewnętrzne decyduje, które wiersze zostaną dotknięte. Poniższy przykład oznacza każdego członka, którego wynajem jest nadal nierozliczony.

UPDATE members
SET reminder_sent = 1
WHERE membership_number IN (SELECT membership_number FROM movierentals WHERE return_date IS NULL);

DELETE z podzapytaniem. Ta sama idea usuwa wiersze, które spełniają warunek przechowywany w drugiej tabeli.

DELETE FROM members
WHERE membership_number NOT IN (SELECT membership_number FROM movierentals);

⚠️ Ostrzeżenie: MySQL Nie pozwala na modyfikację tabeli i wybór z tej samej tabeli w podzapytaniu w klauzuli FROM. Jeśli pojawi się błąd 1093, należy umieścić zapytanie wewnętrzne w tabeli pochodnej, na przykład SELECT * FROM (SELECT ...) AS t, Tak aby MySQL materializuje wynik przed zastosowaniem zmiany. Warto również najpierw uruchomić wewnętrzną instrukcję SELECT i potwierdzić liczbę wierszy przed uruchomieniem Aktualizacja lub DELETE w produkcji.

Podzapytania a łączenia

Zarówno podzapytanie, jak i JOIN mogą łączyć informacje z więcej niż jednej tabeli, więc naturalnym pytaniem jest, którą opcję wybrać.

W porównaniu z łączeniami, podzapytania są proste w użyciu i czytelne. Nie są tak skomplikowane jak Łączyi dlatego są często używane przez Początkujący SQL.

Jednak podzapytania mają problemy z wydajnością. Użycie sprzężenia zamiast podzapytania może czasami przynieść nawet 500-krotny wzrost wydajności, ponieważ optymalizator może rozwiązać sprzężenie w jednym przebiegu, zamiast wielokrotnie oceniać wewnętrzne polecenie.

Punkt porównania Podzapytanie DOŁĄCZ
czytelność Wysoko, ponieważ każdy blok odpowiada na jedno pytanie Niższy, ponieważ wszystkie tabele znajdują się w jednej klauzuli
Wydajność Wolniej, wewnętrzne zapytanie może być uruchamiane dla każdego zewnętrznego wiersza Szybciej, często z bardzo dużą przewagą
Kolumny wyników Zwracane są tylko kolumny tabeli zewnętrznej Można zwrócić kolumny z każdej połączonej tabeli
Typowe zastosowanie Filtrowanie według wartości, którą należy najpierw obliczyć Łączenie powiązanych wierszy z dwóch lub więcej tabel
Krzywa uczenia się Łagodny, znajomy dla początkujących Bardziej strome, wymaga znajomości typów połączeń

Mając wybór, zaleca się użycie JOIN zamiast zapytania podrzędnego. Podzapytania należy stosować wyłącznie jako rozwiązanie awaryjne, gdy nie można osiągnąć powyższego celu za pomocą operacji JOIN.

Podzapytania a łączenia

Podzapytania można również łatwo rozbić na pojedyncze logiczne komponenty, co jest bardzo przydatne, gdy testowanie i debugowanie zapytań.

FAQ

Podzapytanie skorelowane odnosi się do kolumny zapytania zewnętrznego, więc jest ono przetwarzane raz dla każdego wiersza zewnętrznego. Podzapytanie nieskorelowane jest niezależne i uruchamiane tylko raz. Podzapytania skorelowane są wydajne, ale zauważalnie wolniejsze w przypadku dużych tabel.

Podzapytanie może znajdować się w klauzuli WHERE, klauzuli HAVING, liście SELECT lub klauzuli FROM, gdzie staje się tabelą pochodną i wymaga aliasu. Jest ono również poprawne wewnątrz instrukcji INSERT, UPDATE i DELETE.

Często tak. Asystenci AI wbudowani w edytory, tacy jak MySQL Workbench może zaproponować odpowiednik DOŁĄCZZawsze porównuj liczbę wierszy i przeczytaj plan EXPLAIN przed zaufaniem przepisaniu, ponieważ obsługa wartości NULL może się różnić.

Tak. Asystenci konwersji tekstu na SQL zamieniają pytanie takie jak „w której kategorii jest najmniej filmów” na zagnieżdżone polecenie SELECT. Dokładność zależy od schematu dostarczonego do modelu, dlatego należy porównać wygenerowane polecenie z rzeczywistymi nazwami tabel.

Błąd pojawia się, gdy podzapytanie umieszczone po operatorze porównania zwraca kilka wierszy. Zastąp operator operatorem IN, ANY lub EXISTS albo zawęź wewnętrzną klauzulę WHERE, aby zwracany był tylko jeden wiersz.

Podsumuj ten post następująco: