Joins Overview
customers table, product details live once in a products table, and an order simply references the customer_id and product_id it needs. A join is how you recombine that related data across tables for a single query.Why joins exist
customers, products, orders, and order_items. An order row only stores a customer_id, not the customer’s name or email — that would duplicate data across every order the same customer places. Likewise, each row in order_items stores a product_id rather than repeating the product’s full name and price on every line item. Joins let you ask questions that span these tables, such as “which customer placed order 1042, and what products were in it?”, in a single query.General syntax
The general shape of a join
SELECT columns FROM table_a JOIN_TYPE table_b ON table_a.some_column = table_b.matching_column;
ON clause tells PostgreSQL how rows in one table relate to rows in the other — almost always a foreign key on one side matching a primary key on the other.Orders joined to the customers who placed them
SELECT o.order_id, o.order_date, c.first_name, c.last_name FROM orders o JOIN customers c ON c.customer_id = o.customer_id;
Order line items joined to the products they reference
SELECT oi.order_id, p.name, oi.quantity, p.price FROM order_items oi JOIN products p ON p.product_id = oi.product_id;
Join types covered in this section
Join type | Returns |
|---|---|
| Only rows that have a match on both sides (the default for a bare |
| All rows from the left table, with NULLs for unmatched right-side columns |
| All rows from the right table, with NULLs for unmatched left-side columns |
| All rows from both tables, matched where possible, NULLs elsewhere |
| Every combination of rows from both tables (the Cartesian product) |
Self join | A table joined to itself, typically to relate rows to other rows in the same table |
ON condition, which pairs belong together. What differs between join types is only what happens to rows that don’t find a match. The following pages work through each type with the same sample schema.Joins let you query across normalized tables without duplicating data
The ON clause defines how rows from each table are related
Which join type you pick determines what happens to unmatched rows