0
0
PostgresqlComparisonIntermediate · 4 min read

Lateral Join vs Subquery in PostgreSQL: Key Differences and Usage

In PostgreSQL, a LATERAL JOIN allows a subquery to reference columns from preceding tables in the FROM clause, enabling row-wise operations. A subquery is a nested query that runs independently and cannot directly access outer query columns unless correlated. LATERAL joins are more flexible for complex row-by-row computations compared to standard subqueries.
⚖️

Quick Comparison

This table summarizes the main differences between LATERAL JOIN and subquery in PostgreSQL.

FeatureLATERAL JOINSubquery
Access to outer query columnsYes, can reference columns from preceding tablesOnly if correlated; otherwise no access
Execution styleRow-by-row, for each row of the left tableRuns once or per row if correlated
Use caseComplex row-wise computations and joinsFiltering, aggregation, or simple nested queries
Syntax placementUsed in FROM clause with JOINUsed in SELECT, WHERE, or FROM clauses
PerformanceOften more efficient for dependent subqueriesCan be less efficient if not optimized
⚖️

Key Differences

LATERAL JOIN is a special kind of join that lets a subquery access columns from tables that appear earlier in the FROM clause. This means it can perform calculations or fetch related rows for each row of the left table individually, making it very powerful for row-wise operations.

In contrast, a subquery is a query nested inside another query. It can be correlated, meaning it refers to outer query columns, but it runs independently otherwise. Subqueries are often used for filtering or aggregation but lack the flexibility of lateral joins for complex row-by-row logic.

Because LATERAL executes the subquery for each row of the left table, it can be more efficient and expressive when you need to join with a set of rows that depend on each row of the main table. Subqueries, especially uncorrelated ones, run once and return a result used by the outer query.

⚖️

Code Comparison

Example: For each customer, find their latest order using LATERAL JOIN.

sql
SELECT c.customer_id, c.customer_name, o.order_id, o.order_date
FROM customers c
JOIN LATERAL (
  SELECT order_id, order_date
  FROM orders
  WHERE orders.customer_id = c.customer_id
  ORDER BY order_date DESC
  LIMIT 1
) o ON true;
Output
customer_id | customer_name | order_id | order_date ------------+---------------+----------+------------ 1 | Alice | 101 | 2024-05-10 2 | Bob | 105 | 2024-05-12 3 | Carol | 110 | 2024-05-15
↔️

Subquery Equivalent

Using a correlated subquery in the SELECT clause to get the latest order per customer.

sql
SELECT c.customer_id, c.customer_name,
  (SELECT o.order_id
   FROM orders o
   WHERE o.customer_id = c.customer_id
   ORDER BY o.order_date DESC
   LIMIT 1) AS latest_order_id,
  (SELECT o.order_date
   FROM orders o
   WHERE o.customer_id = c.customer_id
   ORDER BY o.order_date DESC
   LIMIT 1) AS latest_order_date
FROM customers c;
Output
customer_id | customer_name | latest_order_id | latest_order_date ------------+---------------+-----------------+------------------ 1 | Alice | 101 | 2024-05-10 2 | Bob | 105 | 2024-05-12 3 | Carol | 110 | 2024-05-15
🎯

When to Use Which

Choose LATERAL JOIN when you need to join each row of a table with a set of rows or computations that depend on that row, especially for complex or multiple columns. It is ideal for row-wise operations and can improve readability and performance.

Use correlated subqueries when you want to fetch single values related to each row, especially in SELECT or WHERE clauses, and the logic is simple. For independent queries or simple filters, standard subqueries work well.

Key Takeaways

LATERAL JOIN lets subqueries access preceding table columns for row-wise operations.
Subqueries run independently unless correlated, limiting direct access to outer columns.
Use LATERAL JOIN for complex joins needing per-row dependent data.
Correlated subqueries are simpler for fetching single related values per row.
Performance can be better with LATERAL JOIN for dependent subqueries.