PostgreSQL Joins
JOINs are how PostgreSQL connects data from different tables.
Theyβre essential when you need to combine related information stored across multiple tables.
π What Are JOINs?
When data is stored in separate tables (like customers and orders), JOINs let you pull that data together into a single result.
Think of it like: Connecting puzzle pieces to see the full picture.
π¦ Basic JOIN Syntax
SELECT columnsFROM table1JOIN table2 ON table1.column = table2.column;π§© Types of JOINs
Each JOIN type gives you different results depending on what data you need.
1. INNER JOIN β Common Ground
Returns rows that have matching values in both tables.
Example: Find customers and their orders
SELECT customers.name, orders.order_date, orders.totalFROM customersINNER JOIN orders ON customers.id = orders.customer_id;β
Gets only customers who have placed orders
β
Gets only orders that have assigned customers
β
Excludes unmatched records from both sides
2. LEFT JOIN (or LEFT OUTER JOIN) β Complete Left Side
Returns all rows from the left table, plus matched data from the right.
Example: Show all customers, including those without orders
SELECT customers.name, orders.order_date, orders.totalFROM customersLEFT JOIN orders ON customers.id = orders.customer_id;β
Gets all customers (even without orders)
β
Shows order info where available
β
Shows NULL for customers without orders
3. RIGHT JOIN (or RIGHT OUTER JOIN) β Complete Right Side
Returns all rows from the right table, plus matched data from the left.
Example: Show all orders, even if customer info is missing
SELECT customers.name, orders.order_date, orders.totalFROM customersRIGHT JOIN orders ON customers.id = orders.customer_id;β
Gets all orders (even those without customer data)
β
Shows customer info where available
β
Shows NULL when customer record is missing
4. FULL OUTER JOIN β All Records
Returns all rows from both tables, whether they match or not.
SELECT customers.name, orders.order_date, orders.totalFROM customersFULL OUTER JOIN orders ON customers.id = orders.customer_id;β
Gets all customers and all orders
β
Shows matches where they exist
β
Shows NULL values where no match occurs
5. CROSS JOIN β All Combinations
Returns the Cartesian product of both tablesβevery row from the first table is paired with every row from the second.
Example: Pair every customer with every order
SELECT customers.name, orders.order_date, orders.totalFROM customersCROSS JOIN orders;β
Useful for generating all possible combinations
β
Can produce large result sets quickly
β
No JOIN condition needed
π― JOIN Examples with Sample Data
Letβs say we have two tables:
customers table:
| id | name | |
|---|---|---|
| 1 | Alice | alice@email.com |
| 2 | Bob | bob@email.com |
| 3 | Charlie | charlie@email.com |
orders table:
| id | customer_id | total | order_date |
|---|---|---|---|
| 101 | 1 | 50.00 | 2023-01-15 |
| 102 | 1 | 30.00 | 2023-02-10 |
| 103 | 2 | 75.00 | 2023-03-22 |
INNER JOIN Result:
| name | total | order_date |
|---|---|---|
| Alice | 50.00 | 2023-01-15 |
| Alice | 30.00 | 2023-02-10 |
| Bob | 75.00 | 2023-03-22 |
(No Charlie because no orders)
LEFT JOIN Result:
| name | total | order_date |
|---|---|---|
| Alice | 50.00 | 2023-01-15 |
| Alice | 30.00 | 2023-02-10 |
| Bob | 75.00 | 2023-03-22 |
| Charlie | NULL | NULL |
π Multiple JOINs
You can connect more than two tables:
SELECT customers.name, orders.total, products.nameFROM customersJOIN orders ON customers.id = orders.customer_idJOIN products ON orders.product_id = products.id;β οΈ Common JOIN Mistakes to Avoid
-
Forgetting the JOIN condition
-- β This creates a Cartesian product (bad!)SELECT * FROM table1 JOIN table2; -
Using wrong column names
-- β Wrong columnsSELECT * FROM customers JOIN orders ON customers.id = orders.id; -
Not considering NULL values
-- β Handle NULL properlySELECT customers.name, COALESCE(orders.total, 0)FROM customersLEFT JOIN orders ON customers.id = orders.customer_id;
π― When to Use Each JOIN Type
| JOIN Type | Use When | Example |
|---|---|---|
| INNER JOIN | Need only matching records | Customers who placed orders |
| LEFT JOIN | Need all records from first table | All customers, with order data if available |
| RIGHT JOIN | Need all records from second table | All orders, with customer data if available |
| FULL OUTER JOIN | Need all records from both tables | Complete data audit |
π οΈ Practical Use Cases
Case 1: Customer Order Analysis
SELECT customers.name, COUNT(orders.id) AS order_count, SUM(orders.total) AS total_spentFROM customersLEFT JOIN orders ON customers.id = orders.customer_idGROUP BY customers.id, customers.nameORDER BY total_spent DESC;Case 2: Inventory Report
SELECT products.name, categories.category_name, suppliers.company_nameFROM productsJOIN categories ON products.category_id = categories.idLEFT JOIN suppliers ON products.supplier_id = suppliers.id;π Quick Summary
- JOINs connect tables using matching column values
- INNER JOIN β Only matching records from both tables
- LEFT JOIN β All records from left table, matched data from right
- RIGHT JOIN β All records from right table, matched data from left
- FULL OUTER JOIN β All records from both tables
- CROSS JOIN β All combinations of rows from both tables
- Always include proper JOIN conditions to avoid performance issues