Bird
Raised Fist0
PostgreSQLquery~10 mins

Self join patterns in PostgreSQL - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Self join patterns
Start with one table
↓
Create two aliases of the same table
↓
Join aliases on a condition
↓
Select columns from both aliases
↓
Return combined rows
↓
End
A self join uses two aliases of the same table to compare rows within it by joining on a condition.
Execution Sample
PostgreSQL
SELECT e1.name AS employee, e2.name AS manager
FROM employees e1
JOIN employees e2 ON e1.manager_id = e2.id;
This query finds each employee and their manager by joining the employees table to itself.
Execution Table
StepActione1.namee1.manager_ide2.ide2.nameJoin Condition (e1.manager_id = e2.id)Output Row
1Check first e1 row (Alice, manager_id=2) against all e2 rowsAlice21Bob2=1? No
2Check Alice against e2 row (2, Carol)Alice22Carol2=2? Yes(Alice, Carol)
3Check Alice against e2 row (3, Dave)Alice23Dave2=3? No
4Check second e1 row (Bob, manager_id=3) against all e2 rowsBob31Bob3=1? No
5Check Bob against e2 row (2, Carol)Bob32Carol3=2? No
6Check Bob against e2 row (3, Dave)Bob33Dave3=3? Yes(Bob, Dave)
7Check third e1 row (Carol, manager_id=NULL) against all e2 rowsCarolNULL1BobNULL=1? No
8Check Carol against e2 row (2, Carol)CarolNULL2CarolNULL=2? No
9Check Carol against e2 row (3, Dave)CarolNULL3DaveNULL=3? No
10No more e1 rows to checkEnd
💡 All rows from e1 checked against e2; join condition false or true determined output rows.
Variable Tracker
VariableStartAfter 1After 2After 3Final
e1.nameAliceAliceBobBobCarol
e1.manager_id2233NULL
e2.id12333
e2.nameBobCarolDaveDaveDave
Key Moments - 2 Insights
Why do we need to use aliases like e1 and e2 in a self join?
Because we join the same table to itself, aliases let us treat each copy separately. See execution_table rows where e1 and e2 columns are compared.
What happens if the join condition uses NULL values?
NULL compared to any value is never true, so those rows don't join. See execution_table rows 7-9 where e1.manager_id is NULL and no output row is produced.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the output row when e1.name is 'Bob' and e2.name is 'Dave'?
A(Bob, Dave)
B(Dave, Bob)
C(Bob, Carol)
D(Carol, Dave)
💡 Hint
Check execution_table row 6 where join condition is true for Bob and Dave.
At which step does the join condition first evaluate to true?
AStep 1
BStep 4
CStep 2
DStep 6
💡 Hint
Look at execution_table row 2 where Alice joins with Carol.
If e1.manager_id for Carol was 1 instead of NULL, what output row would appear?
A(Carol, Carol)
B(Carol, Bob)
C(Carol, Dave)
DNo new output row
💡 Hint
Refer to variable_tracker and execution_table rows 7-9 for NULL behavior and matching ids.
Concept Snapshot
Self join uses the same table twice with aliases.
Join condition compares rows within the table.
Syntax: FROM table AS e1 JOIN table AS e2 ON condition.
Useful for hierarchical or related data in one table.
NULLs do not match in join conditions.
Output combines columns from both aliases.
Full Transcript
A self join means joining a table to itself using two different names called aliases. We compare rows inside the same table by joining on a condition. For example, to find employees and their managers in one employees table, we join employees as e1 to employees as e2 where e1.manager_id equals e2.id. We check each row of e1 against all rows of e2. If the join condition is true, we output a combined row. If the join condition involves NULL, it never matches, so no output row is produced. Aliases are necessary to distinguish the two copies of the same table. This pattern helps find relationships inside one table, like hierarchies or pairs.

Practice

(1/5)
1. What is the main purpose of using a self join in PostgreSQL?
easy
A. To join a table to itself to compare rows within the same table
B. To join two different tables based on a common column
C. To create a backup of a table
D. To delete duplicate rows from a table

Solution

  1. Step 1: Understand the concept of self join

    A self join is used when you want to compare rows within the same table by joining the table to itself.
  2. Step 2: Differentiate from other joins

    Other joins combine different tables, but self join works on one table with aliases to distinguish instances.
  3. Final Answer:

    To join a table to itself to compare rows within the same table -> Option A
  4. Quick Check:

    Self join = join table to itself [OK]
Hint: Self join means joining table to itself using aliases [OK]
Common Mistakes:
  • Confusing self join with joining two different tables
  • Thinking self join creates a new table
  • Assuming self join deletes duplicates
2. Which of the following is the correct syntax to perform a self join on a table named employees with aliases e1 and e2?
easy
A. SELECT * FROM employees e1 LEFT JOIN employees e2 ON e1.id = e2.manager_id;
B. SELECT * FROM employees JOIN employees ON employees.manager_id = employees.id;
C. SELECT * FROM employees AS e1, employees AS e2 WHERE e1.id = e2.id;
D. SELECT * FROM employees e1 JOIN employees e2 ON e1.manager_id = e2.id;

Solution

  1. Step 1: Identify correct alias usage

    Using aliases e1 and e2 for the same table employees is necessary to distinguish instances.
  2. Step 2: Check join condition

    The join condition e1.manager_id = e2.id correctly links employees to their managers.
  3. Final Answer:

    SELECT * FROM employees e1 JOIN employees e2 ON e1.manager_id = e2.id; -> Option D
  4. Quick Check:

    Use aliases and proper ON condition [OK]
Hint: Use aliases and ON clause for self join syntax [OK]
Common Mistakes:
  • Not using aliases causing ambiguity
  • Wrong join condition columns
  • Using comma join without ON clause
3. Given the table employees(id, name, manager_id) with data:
id | name  | manager_id
---+-------+-----------
1  | Alice | NULL
2  | Bob   | 1
3  | Carol | 1
4  | Dave  | 2

What will be the output of this query?
SELECT e1.name AS employee, e2.name AS manager
FROM employees e1
LEFT JOIN employees e2 ON e1.manager_id = e2.id
ORDER BY e1.id;
medium
A. [{"employee": "Alice", "manager": null}, {"employee": "Bob", "manager": null}, {"employee": "Carol", "manager": null}, {"employee": "Dave", "manager": null}]
B. [{"employee": "Alice", "manager": null}, {"employee": "Bob", "manager": "Alice"}, {"employee": "Carol", "manager": "Alice"}, {"employee": "Dave", "manager": "Bob"}]
C. [{"employee": "Alice", "manager": "Alice"}, {"employee": "Bob", "manager": "Bob"}, {"employee": "Carol", "manager": "Carol"}, {"employee": "Dave", "manager": "Dave"}]
D. [{"employee": "Alice", "manager": "Bob"}, {"employee": "Bob", "manager": "Carol"}, {"employee": "Carol", "manager": "Dave"}, {"employee": "Dave", "manager": null}]

Solution

  1. Step 1: Understand the join logic

    The LEFT JOIN matches each employee's manager_id to the manager's id, returning manager's name or null if none.
  2. Step 2: Map each employee to their manager

    Alice has no manager (null), Bob and Carol have Alice as manager, Dave has Bob as manager.
  3. Final Answer:

    [{"employee": "Alice", "manager": null}, {"employee": "Bob", "manager": "Alice"}, {"employee": "Carol", "manager": "Alice"}, {"employee": "Dave", "manager": "Bob"}] -> Option B
  4. Quick Check:

    LEFT JOIN matches manager_id to id [OK]
Hint: Match manager_id to id with LEFT JOIN for manager names [OK]
Common Mistakes:
  • Confusing employee and manager columns
  • Using INNER JOIN losing employees without managers
  • Assuming manager_id is employee id
4. Consider this query intended to find pairs of employees who share the same manager:
SELECT e1.name, e2.name
FROM employees e1
JOIN employees e2 ON e1.manager_id = e2.manager_id
WHERE e1.id != e2.id;

What is the main issue with this query?
medium
A. It will return duplicate pairs in both orders (e.g., (Alice, Bob) and (Bob, Alice))
B. It will not return any rows because of the WHERE clause
C. It causes a syntax error due to missing aliases
D. It only returns employees with no manager

Solution

  1. Step 1: Analyze join condition

    The join matches employees with the same manager_id, including reversed pairs.
  2. Step 2: Check WHERE clause effect

    WHERE e1.id != e2.id avoids self-pairing but does not prevent duplicate pairs in reverse order.
  3. Final Answer:

    It will return duplicate pairs in both orders (e.g., (Alice, Bob) and (Bob, Alice)) -> Option A
  4. Quick Check:

    Self join can produce reversed duplicate pairs [OK]
Hint: Self join pairs may appear twice reversed; use filtering [OK]
Common Mistakes:
  • Assuming WHERE clause removes duplicates
  • Thinking query causes syntax error
  • Believing it returns only employees without managers
5. You want to find all employees who are managers themselves, i.e., employees who have at least one other employee reporting to them. Which self join query correctly achieves this?
hard
A. SELECT e1.name FROM employees e1 JOIN employees e2 ON e1.manager_id = e2.id;
B. SELECT e1.name FROM employees e1 LEFT JOIN employees e2 ON e1.id = e2.manager_id WHERE e2.id IS NULL;
C. SELECT DISTINCT e1.name FROM employees e1 JOIN employees e2 ON e1.id = e2.manager_id;
D. SELECT e1.name FROM employees e1 WHERE e1.manager_id IS NOT NULL;

Solution

  1. Step 1: Understand the requirement

    Managers are employees whose id appears as manager_id for others.
  2. Step 2: Analyze each option

    SELECT DISTINCT e1.name FROM employees e1 JOIN employees e2 ON e1.id = e2.manager_id; joins employees where e1.id = e2.manager_id, selecting distinct managers correctly.
  3. Final Answer:

    SELECT DISTINCT e1.name FROM employees e1 JOIN employees e2 ON e1.id = e2.manager_id; -> Option C
  4. Quick Check:

    Join on id = manager_id finds managers [OK]
Hint: Join employees where id = manager_id to find managers [OK]
Common Mistakes:
  • Using LEFT JOIN with IS NULL returns non-managers
  • Joining on wrong columns (manager_id = id reversed)
  • Filtering on manager_id IS NOT NULL returns employees with managers
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard