Discover how to fetch related data for each row effortlessly with one simple trick!
Why LATERAL subqueries in PostgreSQL? - Purpose & Use Cases
Imagine you have a list of customers and for each customer, you want to find their latest order details. Doing this manually means checking each customer one by one and then searching through all orders to find the latest one.
This manual approach is slow and tiring because you repeat the same search many times. It's easy to make mistakes, like mixing up orders or missing the latest one. Also, writing separate queries for each customer is confusing and hard to manage.
LATERAL subqueries let you write one smart query that looks at each customer and immediately finds their latest order. It works like a helper that can use information from the current customer row to find matching orders quickly and cleanly.
SELECT customer_id FROM customers; -- Then for each customer, run: SELECT * FROM orders WHERE customer_id = ? ORDER BY order_date DESC LIMIT 1;
SELECT c.customer_id, o.*
FROM customers c,
LATERAL (
SELECT * FROM orders o WHERE o.customer_id = c.customer_id ORDER BY order_date DESC LIMIT 1
) o;It enables writing clear and efficient queries that combine related data row-by-row without complex joins or repeated queries.
A store manager wants to see each customer's most recent purchase to offer personalized discounts. Using LATERAL subqueries, they get this info instantly for all customers in one go.
LATERAL subqueries let you use data from one row to find related rows easily.
They simplify queries that need to look up matching details for each item in a list.
This makes your database work faster and your queries easier to read.
Practice
LATERAL in a PostgreSQL query?Solution
Step 1: Understand the role of LATERAL
LATERAL allows a subquery to access columns from tables that appear earlier in the FROM clause.Step 2: Compare with other options
The other options describe different features unrelated to LATERAL's purpose.Final Answer:
To allow a subquery to reference columns from tables listed before it in the FROM clause -> Option AQuick Check:
LATERAL = subquery uses previous table columns [OK]
- Thinking LATERAL creates temporary tables
- Confusing LATERAL with query parallelism
- Assuming LATERAL enforces constraints
Solution
Step 1: Identify correct LATERAL syntax
The correct syntax uses CROSS JOIN LATERAL with a subquery in parentheses and an alias.Step 2: Check each option
SELECT * FROM table1, (SELECT * FROM table2 WHERE table2.id = table1.id) sub; misses LATERAL keyword causing reference error; SELECT * FROM table1 JOIN LATERAL table2 ON table2.id = table1.id; uses JOIN LATERAL incorrectly without parentheses; SELECT * FROM table1 LATERAL JOIN table2 ON table2.id = table1.id; has invalid syntax.Final Answer:
SELECT * FROM table1 CROSS JOIN LATERAL (SELECT * FROM table2 WHERE table2.id = table1.id) sub; -> Option CQuick Check:
Correct LATERAL syntax = SELECT * FROM table1 CROSS JOIN LATERAL (SELECT * FROM table2 WHERE table2.id = table1.id) sub; [OK]
- Omitting LATERAL keyword
- Not aliasing the subquery
- Using LATERAL without parentheses
users(id, name) and orders(user_id, amount), what does this query return?SELECT u.name, o.total FROM users u CROSS JOIN LATERAL (SELECT SUM(amount) AS total FROM orders WHERE user_id = u.id) o;
Solution
Step 1: Analyze the LATERAL subquery
The subquery sums orders per user using user_id = u.id, so it calculates total per user.Step 2: Understand CROSS JOIN LATERAL effect
It runs the subquery for each user, returning their name and total order amount, including users with zero orders (total will be NULL).Final Answer:
Each user with the total amount of their orders -> Option AQuick Check:
LATERAL sums orders per user = Each user with the total amount of their orders [OK]
- Thinking it returns all orders without grouping
- Assuming only users with orders appear
- Confusing CROSS JOIN LATERAL with INNER JOIN
SELECT t1.id, t2.val FROM table1 t1 JOIN LATERAL (SELECT val FROM table2 WHERE table2.ref = t1.id) t2;
Solution
Step 1: Check alias usage
The subquery is aliased as t2, so no issue there.Step 2: Verify JOIN LATERAL syntax
JOIN LATERAL without CROSS is valid syntax in PostgreSQL; CROSS JOIN LATERAL is one form, but JOIN LATERAL alone is allowed as INNER JOIN LATERAL.Step 3: Confirm subquery column count
Subquery returns one column 'val', which is acceptable.Final Answer:
No error; query is correct -> Option DQuick Check:
JOIN LATERAL syntax without CROSS is valid = No error [OK]
- Using JOIN LATERAL without CROSS
- Forgetting subquery alias
- Expecting subquery to return multiple columns
SELECT c.name, o.order_id, o.amount FROM customers c CROSS JOIN LATERAL (SELECT order_id, amount FROM orders WHERE customer_id = c.id ORDER BY amount DESC LIMIT 2) o;
Solution
Step 1: Understand LATERAL with LIMIT
The subquery selects top 2 orders per customer by ordering and limiting results.Step 2: Check if query returns all customers
CROSS JOIN LATERAL runs subquery per customer; if no orders, no rows for that customer appear.Step 3: Confirm correctness
The query correctly lists each customer with up to 2 highest orders; no syntax or logic errors.Final Answer:
This query correctly lists each customer with their top 2 orders -> Option BQuick Check:
LATERAL with LIMIT works for top N per row [OK]
- Thinking GROUP BY is needed here
- Believing LATERAL disallows LIMIT
- Assuming all customers appear even without orders
Ready to prove it?
Pass the test and this pattern moves unknown
