0Pricing
Coding Interview Prep · Lekcja

Łączenie wielu CTE

Budowanie potoku nazwanych etapów odwołujących się do siebie nawzajem

Łączenie wielu CTE to bezpłatna lekcja Coding Interview Prep 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 Coding Interview Prep, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Coding Interview Prep zawiera 4 lekcji w sumie.

Dlaczego warto łączyć CTE

Rzeczywiste zadania rekrutacyjne rzadko dają się rozwiązać w jednym kroku. Łączenie CTE pozwala zbudować potok nazwanych etapów, w którym każdy etap przekształca wynik poprzedniego. Odzwierciedla to sposób, w jaki doświadczony inżynier rozkłada trudne zapytanie na łatwiejsze do opanowania części.

Zamiast zagnieżdżać podzapytania na trzech poziomach, zapisują Państwo każdy krok raz, nadają mu nazwę i pozwalają kolejnym krokom się do niego odwoływać.

Składnia z elementami oddzielonymi przecinkami

Aby zdefiniować kilka CTE, należy raz zapisać WITH, a następnie oddzielić każdy nazwany blok przecinkiem. Nie należy powtarzać słowa kluczowego WITH.

  • Jedno WITH na początku.
  • Przecinek między każdymi dwiema definicjami CTE.
  • Brak przecinka przed końcowym głównym zapytaniem.
WITH a AS (
    SELECT customer_id FROM orders
),
b AS (
    SELECT customer_id FROM a
)
SELECT *
FROM b;

Późniejsze CTE mogą odwoływać się do wcześniejszych

Na tym polega siła łączenia: CTE może odczytywać dane z dowolnego CTE zdefiniowanego wcześniej. Ta widoczność wyłącznie w kierunku wcześniejszych definicji pozwala budować łańcuch zależności.

Wcześniejsze CTE nie widzi późniejszego, dlatego kolejność ma znaczenie. Etapy należy układać od danych surowych do ostatecznego kształtu wyniku.

WITH filtered AS (
    SELECT *
    FROM events
    WHERE event_type = 'purchase'
),
per_user AS (
    SELECT user_id, COUNT(*) AS purchases
    FROM filtered
    GROUP BY user_id
)
SELECT *
FROM per_user;

Przykład: potok złożony z trzech etapów

Pytanie: jaka jest średnia kwota wydatków wśród klientów, którzy wydali ponad 1000 dolarów? Należy podzielić je na trzy etapy: obliczyć łączne wydatki na klienta, odfiltrować klientów wydających duże kwoty, a następnie obliczyć ich średnią.

Nazwa każdego CTE opisuje jego cel, dzięki czemu osoba sprawdzająca od razu rozumie przebieg operacji.

WITH spend AS (
    SELECT customer_id, SUM(amount) AS total
    FROM orders
    GROUP BY customer_id
),
big_spenders AS (
    SELECT customer_id, total
    FROM spend
    WHERE total > 1000
)
SELECT AVG(total) AS avg_big_spend
FROM big_spenders;

Kolejność definicji ma znaczenie

Ponieważ widoczność działa tylko w kierunku wcześniejszych definicji, CTE zależne od innego CTE musi znajdować się za swoją zależnością. Jeśli odwołają się Państwo do nazwy, która nie została jeszcze zdefiniowana, baza danych zgłosi błąd „relation does not exist”.

Dobry nawyk: należy czytać listę CTE od góry do dołu i sprawdzać, czy każda użyta nazwa pojawiła się już wcześniej.

Odwoływanie się do jednego CTE z wielu innych

Pojedyncze CTE może zasilać kilka kolejnych CTE. W tym miejscu łączenie wygrywa z zagnieżdżonymi podzapytaniami: wynik bazowy jest obliczany raz, a następnie można na jego podstawie utworzyć kilka gałęzi.

W tym przykładzie zarówno active, jak i recent odczytują dane z base, dzięki czemu unikamy powielania logiki.

WITH base AS (
    SELECT * FROM users WHERE deleted = false
),
active AS (
    SELECT id FROM base WHERE last_login > NOW() - INTERVAL '7 days'
),
recent AS (
    SELECT id FROM base WHERE created_at > NOW() - INTERVAL '30 days'
)
SELECT (SELECT COUNT(*) FROM active) AS active_cnt,
       (SELECT COUNT(*) FROM recent) AS recent_cnt;

Łączenie dwóch CTE

Połączone CTE są często łączone w głównym zapytaniu. Należy obliczyć każdą stronę osobno, a następnie je połączyć. Dzięki temu każde obliczenie pozostaje odizolowane, a samo łączenie jest proste.

Poniżej niezależnie obliczamy liczbę zamówień i liczbę zwrotów, a następnie łączymy wyniki dla każdego klienta.

WITH orders_cte AS (
    SELECT customer_id, COUNT(*) AS orders
    FROM orders GROUP BY customer_id
),
refunds_cte AS (
    SELECT customer_id, COUNT(*) AS refunds
    FROM refunds GROUP BY customer_id
)
SELECT o.customer_id, o.orders, COALESCE(r.refunds, 0) AS refunds
FROM orders_cte o
LEFT JOIN refunds_cte r ON r.customer_id = o.customer_id;

Czytelność zamiast zagnieżdżania

Proszę porównać podzapytanie zagnieżdżone na trzech poziomach z potokiem złożonym z trzech CTE. Wersja zagnieżdżona zmusza czytelnika do mentalnego rozwijania zapytania od środka na zewnątrz. Wersję z CTE czyta się w kolejności wykonywania, od góry do dołu.

Osoby prowadzące rozmowy rekrutacyjne doceniają podejście z CTE, ponieważ właśnie taki kod chciałyby utrzymywać na produkcji. Nazwanie każdego etapu to dokumentacja, która nigdy się nie dezaktualizuje.

Częsty błąd przy łączeniu CTE

Początkujący często dodają przecinek po ostatnim CTE, tuż przed głównym SELECT. Taki końcowy przecinek powoduje błąd składni.

  • Przecinki występują wyłącznie między definicjami CTE.
  • Po końcowym nawiasie zamykającym bezpośrednio następuje główne zapytanie — bez przecinka.

Inna pułapka to zapomnienie, że każde CTE musi zawierać własne kompletne zapytanie SELECT wewnątrz nawiasów.

Czy każdy etap jest wykonywany osobno

To istotna kwestia rekrutacyjna: logicznie potok składa się z odrębnych kroków, ale optymalizator może rozwinąć je bezpośrednio i połączyć w jeden plan wykonania. W większości silników nie muszą Państwo płacić za materializację wyników pośrednich.

Łączenie CTE pomaga więc Państwu rozumieć zapytanie, niekoniecznie pogarszając wydajność. Warto o tym wspomnieć, aby pokazać szerszą wiedzę.

Nazywanie etapów jak elementów potoku

Dobre nazwy etapów zamieniają zapytanie w kod, który sam się dokumentuje. Lepiej wybierać nazwy opisujące wynik każdego kroku niż wykonywaną operację.

  • spend i big_spenders są lepsze niż step1 i step2.
  • Na podstawie samych nazw CTE czytelnik powinien móc odtworzyć cały przebieg.
  • Spójne nazewnictwo etapów sprawia, że łączenie w głównym zapytaniu staje się oczywiste.

Podczas rozmowy rekrutacyjnej jasne nazwanie etapów pokazuje, że potrafią Państwo pisać łatwy w utrzymaniu produkcyjny kod SQL.

Szybkie sprawdzenie

Sprawdź, jak dobrze rozumiesz wzajemne odwołania między połączonymi CTE.

Podsumowanie: łączenie CTE

Poznali Państwo sposób budowania potoków: jedno WITH, definicje CTE oddzielone przecinkami oraz widoczność wyłącznie w kierunku wcześniejszych definicji, dzięki której każdy etap może odczytywać dane z wcześniejszych etapów.

  • CTE należy porządkować od danych surowych do końcowego wyniku.
  • Bazowe CTE można ponownie wykorzystywać w kilku kolejnych krokach.
  • Przed głównym zapytaniem nie może być końcowego przecinka.
  • Łączenie poprawia czytelność, niekoniecznie pogarszając wydajność.

Następnie: porównanie CTE z podzapytaniami i tabelami tymczasowymi.

Często zadawane pytania

Czy lekcja „Łączenie wielu CTE” jest bezpłatna?

Tak — pełny tekst „Łączenie wielu CTE” 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 Coding Interview Prep, przejdź na CoddyKit PRO. Kurs Coding Interview Prep zawiera 4 lekcji w sumie.

Co nauczysz się w „Łączenie wielu CTE”?

Budowanie potoku nazwanych etapów odwołujących się do siebie nawzajem Ćwiczysz Coding Interview Prep 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ąć Coding Interview Prep?

Nie wymagamy żadnego doświadczenia. Coding Interview Prep 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 „Łączenie wielu CTE”?

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 Coding Interview Prep?

Tak. Każda lekcja Coding Interview Prep 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. Pisanie pierwszego CTE
  2. Łączenie wielu CTE
  3. CTE a podzapytanie i tabela tymczasowa
  4. Refaktoryzacja zagnieżdżonych zapytań do CTE
← Powrót do Coding Interview Prep