Introduction
LATERAL join lets you run a subquery for each row of a table, using values from that row. It helps when you want to get related data that depends on each row.
SELECT columns FROM table1 JOIN LATERAL ( SELECT columns FROM table2 WHERE table2.column = table1.column LIMIT n ) alias ON true;
SELECT c.customer_id, 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;
SELECT p.product_id, r.review_text FROM products p JOIN LATERAL ( SELECT review_text FROM reviews WHERE reviews.product_id = p.product_id ORDER BY rating DESC LIMIT 1 ) r ON true;
CREATE TABLE customers (customer_id INT, name TEXT); CREATE TABLE orders (order_id INT, customer_id INT, order_date DATE); INSERT INTO customers VALUES (1, 'Alice'), (2, 'Bob'); INSERT INTO orders VALUES (101, 1, '2024-01-10'), (102, 1, '2024-02-15'), (103, 2, '2024-01-20'); SELECT c.customer_id, c.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 ORDER BY c.customer_id;
LATERAL join in PostgreSQL?users(id, name)orders(id, user_id, amount)SELECT u.name, o.amount FROM users u JOIN LATERAL (SELECT amount FROM orders WHERE user_id = u.id ORDER BY amount DESC LIMIT 1) o ON true;
SELECT u.name, o.amount FROM users u JOIN LATERAL (SELECT amount FROM orders WHERE user_id = u.id ORDER BY amount DESC LIMIT 1) o;
Pass the test and this pattern moves unknown