0Pricing
SQL Academy · Lekcja

Podzapytania skorelowane i nieskorelowane

Poznaj podzapytania skorelowane, które odwołują się do wiersza zewnętrznego, ich charakterystykę wydajnościową oraz sytuacje, w których EXISTS jest lepsze od IN.

Podzapytania skorelowane i nieskorelowane to bezpłatna lekcja SQL Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej SQL Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs SQL Academy zawiera 4 lekcji w sumie.

Podzapytania nieskorelowane

Podzapytanie nieskorelowane nie odwołuje się do wiersza zewnętrznego. Jest wykonywane raz, a jego wynik jest ponownie wykorzystywany:

SELECT * FROM users
WHERE id IN (
  SELECT user_id FROM orders WHERE status = 'paid'
);

Podzapytania skorelowane

Podzapytanie skorelowane odwołuje się do wiersza zewnętrznego — logicznie jest wykonywane ponownie dla każdego wiersza zewnętrznego:

SELECT u.id, u.email
FROM users u
WHERE EXISTS (
  SELECT 1 FROM orders o
  WHERE o.user_id = u.id
    AND o.total > 1000
);

Jak rozpoznać różnicę

Jeśli wewnętrzna instrukcja SELECT odwołuje się do kolumny z zewnętrznego FROM, podzapytanie jest skorelowane.

Wpływ na wydajność

Naiwne podzapytanie skorelowane ma złożoność O(outer × inner). Współczesne planery często przepisują je na semi-join lub hash join — mimo to, gdy jest to możliwe, należy pisać prostszą formę.

EXISTS a IN

W przypadku sprawdzania „co najmniej jednego dopasowania”:

-- IN with non-correlated subquery (often the planner's favourite):
SELECT u.* FROM users u
WHERE u.id IN (SELECT user_id FROM orders);

-- EXISTS with correlated subquery (NULL-safe alternative):
SELECT u.* FROM users u
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);

NOT EXISTS zawsze lepsze niż NOT IN

NOT IN nie działa poprawnie, gdy zbiór wewnętrzny zawiera NULL. NOT EXISTS nie ma tego problemu. W przypadku antyzłączenia zawsze należy preferować NOT EXISTS:

-- BUG-prone:
SELECT u.* FROM users u
WHERE u.id NOT IN (SELECT excluded_id FROM blocklist);

-- Safe:
SELECT u.* FROM users u
WHERE NOT EXISTS (SELECT 1 FROM blocklist b WHERE b.excluded_id = u.id);

Podzapytania skorelowane w SELECT

Wzorzec „wyszukiwania dla każdego wiersza”:

SELECT u.id, u.email,
  (SELECT MAX(created_at) FROM orders o WHERE o.user_id = u.id) AS last_order_at
FROM users u;

-- Often readable, but consider a LEFT JOIN + GROUP BY.

Podzapytania skorelowane w UPDATE

Pobierz wyprowadzoną wartość dla każdego wiersza:

UPDATE products p
SET review_count = (
  SELECT COUNT(*) FROM reviews r WHERE r.product_id = p.id
);

LATERAL JOIN: czytelniejszy wzorzec skorelowany

W przypadku „wyszukiwania kilku wierszy dla każdego wiersza zewnętrznego” LATERAL jest często czytelniejszy i szybszy — omówiono go w lekcji Zaawansowane wzorce JOIN.

Buforowanie podzapytań

PostgreSQL domyślnie nie buforuje wyników podzapytań między wierszami. Jeśli ten sam wynik wewnętrzny jest potrzebny wiele razy, użyj CTE.

Indeksuj kolumnę korelacji

Wewnętrzne podzapytanie filtruje według klucza wiersza zewnętrznego. Bez indeksu na tym kluczu dla każdego wiersza zewnętrznego wykonywane jest pełne skanowanie.

-- For the orders example, this is essential:
CREATE INDEX orders_user_id_idx ON orders(user_id);

Podsumowanie

Podzapytania skorelowane odwołują się do wiersza zewnętrznego.

  • EXISTS to typowy wzorzec skorelowany
  • Preferuj NOT EXISTS zamiast NOT IN
  • Indeksuj kolumnę korelacji
  • LATERAL jest w wielu przypadkach czytelniejszą alternatywą

Szybkie sprawdzenie

Dlaczego NOT EXISTS jest bezpieczniejsze niż NOT IN, gdy zbiór wewnętrzny może zawierać NULL?

Często zadawane pytania

Czy lekcja „Podzapytania skorelowane i nieskorelowane” jest bezpłatna?

Tak — pełny tekst „Podzapytania skorelowane i nieskorelowane” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu SQL Academy, przejdź na CoddyKit PRO. Kurs SQL Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Podzapytania skorelowane i nieskorelowane”?

Poznaj podzapytania skorelowane, które odwołują się do wiersza zewnętrznego, ich charakterystykę wydajnościową oraz sytuacje, w których EXISTS jest lepsze od IN. Ćwiczysz SQL Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć SQL Academy?

Nie wymagamy żadnego doświadczenia. SQL Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Podzapytania skorelowane i nieskorelowane”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji SQL Academy?

Tak. Każda lekcja SQL Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Podzapytania skalarne, wierszowe i tabelowe
  2. Podzapytania skorelowane i nieskorelowane
  3. Wspólne wyrażenia tabelowe (WITH)
  4. Rekurencyjne CTE dla hierarchii
← Powrót do SQL Academy