0Pricing
SQL Academy · Lekcja

Porównywanie wierszy w tej samej tabeli

Znajduj pary i relacje

Porównywanie wierszy w tej samej tabeli to bezpłatna lekcja SQL Academy na CoddyKit. To lekcja 3 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.

Czym jest self join

Self join to złączenie tabeli z samą sobą. Początkowo może się to wydawać nietypowe, ale jest to skuteczna technika porównywania wierszy w obrębie tej samej tabeli.

Wyobraźmy sobie tabelę employees, w której każdy pracownik ma kolumnę manager_id wskazującą na inny wiersz tej samej tabeli. Self join pozwala dopasować każdego pracownika do jego menedżera w jednym zapytaniu.

Konfigurowanie przykładowej tabeli

Utwórzmy prostą tabelę employees, której będziemy używać w całej lekcji. Każdy wiersz zawiera kolumny id, name, salary i manager_id, która odwołuje się do innego pracownika w tej samej tabeli.

CREATE TABLE employees (
  id         INT PRIMARY KEY,
  name       VARCHAR(50),
  salary     INT,
  manager_id INT
);

INSERT INTO employees VALUES
  (1, 'Alice',   90000, NULL),
  (2, 'Bob',     70000, 1),
  (3, 'Carol',   65000, 1),
  (4, 'Dave',    55000, 2),
  (5, 'Eve',     60000, 2),
  (6, 'Frank',   48000, 3);

Podstawowa składnia self join

Aby wykonać self join, należy odwołać się do tej samej tabeli dwukrotnie, używając dwóch różnych aliasów. Aliasy działają tak, jakby dostępne były dwie osobne kopie tabeli. Następnie należy określić warunek złączenia łączący obie kopie.

W tym przykładzie nadajemy tabeli employees alias e (pracownikowi) oraz m (menedżerowi), a następnie dopasowujemy wiersze na podstawie e.manager_id = m.id.

SELECT
  e.name   AS employee,
  m.name   AS manager
FROM employees e
JOIN employees m ON e.manager_id = m.id;

Uwzględnianie wierszy najwyższego poziomu za pomocą LEFT JOIN

Zwykłe INNER JOIN pomija wiersze, w których manager_id ma wartość NULL, co oznacza, że pracownik najwyższego szczebla (Alice, dyrektorka generalna) zostałby wykluczony z wyników.

Należy użyć LEFT JOIN, aby wyświetlić każdego pracownika, również tych, którzy nie mają menedżera. W ich przypadku kolumna menedżera będzie po prostu zawierać wartość NULL.

SELECT
  e.name          AS employee,
  m.name          AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id
ORDER BY m.name NULLS LAST, e.name;

Wyszukiwanie par współdzielących właściwość

Złączenia tabeli z samą sobą są również przydatne do wyszukiwania par wierszy, które mają wspólną wartość. Można na przykład znaleźć wszystkie pary pracowników podlegających temu samemu menedżerowi.

Warunek a.id < b.id zapobiega pojawieniu się w wynikach obu zduplikowanych par, takich jak (Bob, Carol) i (Carol, Bob).

SELECT
  a.name       AS employee_1,
  b.name       AS employee_2,
  a.manager_id AS shared_manager
FROM employees a
JOIN employees b
  ON a.manager_id = b.manager_id
 AND a.id < b.id;

Porównywanie wynagrodzeń między wierszami

Za pomocą złączenia tabeli z samą sobą można porównywać wartości liczbowe w różnych wierszach. Poniższe zapytanie wyszukuje każdego pracownika, którego wynagrodzenie jest wyższe niż wynagrodzenie jego menedżera — jest to klasyczna kontrola analityczna.

SELECT
  e.name       AS employee,
  e.salary     AS emp_salary,
  m.name       AS manager,
  m.salary     AS mgr_salary
FROM employees e
JOIN employees m ON e.manager_id = m.id
WHERE e.salary > m.salary;

Wyszukiwanie wierszy bez dopasowania

Złączenie tabeli z samą sobą za pomocą LEFT JOIN oraz sprawdzenie WHERE ... IS NULL pozwala znaleźć wiersze, które nie mają pasującego odpowiednika. W tym przykładzie wyszukujemy pracowników, którym nikt nie podlega — węzły liściowe hierarchii.

SELECT e.name AS employee
FROM employees e
LEFT JOIN employees sub ON sub.manager_id = e.id
WHERE sub.id IS NULL
ORDER BY e.name;

Liczenie bezpośrednich podwładnych

Łącząc tabelę z samą sobą i grupując wyniki po stronie menedżera, można policzyć, ilu bezpośrednich podwładnych ma każdy menedżer. Pracownicy bez podwładnych zostaną uwzględnieni dzięki LEFT JOIN.

SELECT
  m.name           AS manager,
  COUNT(e.id)      AS direct_reports
FROM employees m
LEFT JOIN employees e ON e.manager_id = m.id
GROUP BY m.id, m.name
ORDER BY direct_reports DESC;

Używanie CTE do uproszczenia złączeń tabeli z samą sobą

Gdy zapytanie z użyciem self join staje się złożone, opakowanie go we wspólne wyrażenie tabelowe (CTE) ułatwia zrozumienie logiki. Należy zdefiniować jedno CTE dla hierarchii, a następnie wykonać na nim przejrzyste zapytanie.

WITH hierarchy AS (
  SELECT
    e.id         AS emp_id,
    e.name       AS employee,
    e.salary     AS emp_salary,
    m.name       AS manager,
    m.salary     AS mgr_salary
  FROM employees e
  LEFT JOIN employees m ON e.manager_id = m.id
)
SELECT *
FROM hierarchy
WHERE mgr_salary IS NOT NULL
  AND emp_salary > mgr_salary;

Złączenie tabeli z samą sobą dla tabeli niehierarchicznej

Złączenia tabeli z samą sobą nie ograniczają się do hierarchii menedżerów i pracowników. Poniższy przykład wykorzystuje tabelę products do znalezienia wszystkich par produktów należących do tej samej kategorii, co może być przydatne w systemach rekomendacji lub podczas sprawdzania podobieństwa.

CREATE TABLE products (
  id       INT PRIMARY KEY,
  name     VARCHAR(50),
  category VARCHAR(30)
);

INSERT INTO products VALUES
  (1, 'Laptop',  'Electronics'),
  (2, 'Phone',   'Electronics'),
  (3, 'Tablet',  'Electronics'),
  (4, 'Shirt',   'Clothing'),
  (5, 'Jeans',   'Clothing');

SELECT
  a.name AS product_1,
  b.name AS product_2,
  a.category
FROM products a
JOIN products b
  ON a.category = b.category
 AND a.id < b.id;

Pułapki: iloczyny kartezjańskie i duplikaty

Dwa częste błędy przy złączeniach tabeli z samą sobą to iloczyny kartezjańskie (całkowite pominięcie warunku złączenia) oraz zduplikowane pary (użycie a.id <> b.id zamiast a.id < b.id).

Należy zawsze sprawdzić poprawność warunku złączenia i używać < zamiast <>, gdy potrzebne są tylko pary nieuporządkowane, a nie uporządkowane.

-- Wrong: returns every ordered pair (A,B) AND (B,A)
SELECT a.name, b.name
FROM employees a
JOIN employees b ON a.manager_id = b.manager_id
                AND a.id <> b.id;

-- Correct: returns each unordered pair once
SELECT a.name, b.name
FROM employees a
JOIN employees b ON a.manager_id = b.manager_id
                AND a.id < b.id;

Szybki sprawdzian

Proszę sprawdzić swoją wiedzę na temat self joinów i porównywania wierszy w tej samej tabeli.

Podsumowanie lekcji

W tej lekcji poznali Państwo sposób używania self joinów do porównywania wierszy w tej samej tabeli.

Najważniejsze wnioski:

  • Należy nadać tabeli dwa aliasy (np. e i m), aby baza danych traktowała je jako odrębne źródła.
  • Należy użyć INNER JOIN, gdy potrzebne są tylko wiersze mające dopasowanie, oraz LEFT JOIN, gdy należy uwzględnić także wiersze bez dopasowania.
  • Należy użyć a.id < b.id, aby uniknąć zduplikowanych par bez określonej kolejności.
  • Self joiny sprawdzają się w hierarchiach (przełożony/pracownik), wyszukiwaniu podobieństw (ta sama kategoria) oraz wszędzie tam, gdzie trzeba powiązać ze sobą dwa wiersze z tej samej tabeli.
  • CTE mogą znacznie ułatwić odczytywanie i utrzymywanie złożonych zapytań z self joinami.

Często zadawane pytania

Czy lekcja „Porównywanie wierszy w tej samej tabeli” jest bezpłatna?

Tak — pełny tekst „Porównywanie wierszy w tej samej tabeli” 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 „Porównywanie wierszy w tej samej tabeli”?

Znajduj pary i relacje Ć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 3 z 4.

Ile czasu zajmuje lekcja „Porównywanie wierszy w tej samej tabeli”?

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. Czym jest self join
  2. Pracownicy i menedżerowie
  3. Porównywanie wierszy w tej samej tabeli
  4. Ograniczenia self joinów
← Powrót do SQL Academy