Subquery là truy vấn lồng bên trong truy vấn khác (ở SELECT, FROM, hoặc WHERE).
- Subquery độc lập (non-correlated): chạy được một mình, không tham chiếu truy vấn ngoài. DB thường chạy một lần, lấy kết quả rồi dùng cho truy vấn ngoài.
SELECT * FROM products
WHERE price > (SELECT AVG(price) FROM products); -- chạy 1 lần- Correlated subquery: tham chiếu cột của truy vấn ngoài → không chạy độc lập được; về mặt logic nó chạy lặp lại cho từng hàng của truy vấn ngoài.
SELECT e.* FROM employees e
WHERE e.salary > (
SELECT AVG(salary) FROM employees
WHERE dept_id = e.dept_id -- e.dept_id từ truy vấn ngoài
);Khác biệt cốt lõi:
- Sự phụ thuộc: correlated cần giá trị từ ngoài; non-correlated thì không.
- Hiệu năng: correlated có thể tốn hơn (đánh giá theo từng hàng), dù planner hiện đại thường viết lại thành join. Nhiều correlated subquery với EXISTS có thể chuyển thành JOIN/GROUP BY để nhanh hơn.
EXISTS/NOT EXISTS thường đi cùng correlated subquery để kiểm tra tồn tại theo từng hàng. PostgreSQL còn có LATERAL — subquery trong FROM được tham chiếu hàng của bảng đứng trước, hợp bài "top-N mỗi nhóm" (vd 3 đơn mới nhất của mỗi user).