Bài học theo mô-đun (4/4)
Một truy vấn bên trong một truy vấn khác: truy vấn phụ
Bạn đã học cách trích xuất, lọc, nhóm, nối và chuyển đổi. Ở đó là một ý tưởng cơ bản cuối cùng: đặt một truy vấn vào một truy vấn khác. Đây là được gọi là truy vấn phụ và chúng là bước cho phép bạn trả lời các câu hỏi như "ai có thu nhập trên mức trung bình?" hoặc "bộ phận nào có người được giao cho một dự án?".
Cú pháp cơ bản
Truy vấn con là SELECT được gói trong dấu ngoặc đơn, được sử dụng thay cho một truy vấn đơn
giá trị hoặc danh sách các giá trị trong truy vấn khác:
-- Find who earns MORE THAN THE COMPANY AVERAGE:
SELECT first_name, last_name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);Công cụ chạy truy vấn phụ trước tiên — SELECT AVG(salary) FROM employees
trả về một số duy nhất — rồi sử dụng số đó ở bên ngoài WHERE
như thể bạn đã viết nó bằng tay. Đây chính xác là lợi thế: bạn làm được
không cần biết trước giá trị trung bình, SQL sẽ tính giá trị đó cho bạn.
Ba "loại" phổ biến nhất
1. Truy vấn con trả về một giá trị
Ví dụ trên: truy vấn con tạo ra một hàng, một cột (được gọi là
vô hướng). Bạn sử dụng nó với =, >, <, v.v.
-- Employee with the highest salary:
SELECT first_name, last_name
FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);2. Truy vấn con trả về danh sách
Truy vấn con tạo ra một cột, nhiều hàng. Bạn sử dụng nó với
IN (...):
-- Departments that have at least one employee:
SELECT name
FROM departments
WHERE id IN (SELECT DISTINCT department_id
FROM employees
WHERE department_id IS NOT NULL);3. Truy vấn con dưới dạng "bảng" (TỪ)
Truy vấn con cũng có thể thay thế bảng trong FROM. Nó rất hữu ích để
tính toán trước các tập hợp rồi lọc hoặc nối chúng:
-- Departments with average salary above 40000:
SELECT d.name, medie.stipendio_medio
FROM departments AS d
JOIN (SELECT department_id, AVG(salary) AS stipendio_medio
FROM employees
GROUP BY department_id) AS medie
ON d.id = medie.department_id
WHERE medie.stipendio_medio > 40000;Truy vấn phụ hoặc THAM GIA? Khi nào nên sử dụng cái nào
Thông thường, bạn có thể nhận được kết quả tương tự bằng JOIN hoặc bằng truy vấn phụ.
Quy tắc ngón tay cái:
- Để lọc các hàng của một bảng dựa trên thuộc tính của một bảng khác
("nhân viên có bộ phận..."_),
IN (subquery)rất dễ đọc. - Để kết hợp các cột từ nhiều bảng trong kết quả, hãy sử dụng
JOIN. - Để tính tổng và sử dụng nó làm ngưỡng ("trên trung bình"), truy vấn con vô hướng là lựa chọn tự nhiên.
Trong thực tế, bạn sẽ thấy cả hai: công cụ SQL thường tối ưu hóa chúng giống nhau cách. Chọn hình thức đọc tốt nhất.
Hãy thử nó
Tìm tên (first_name), họ (last_name) và mức lương (mức lương) của những nhân viên kiếm được nhiều hơn mức trung bình của công ty. Ba cột.
Hiển thị gợi ý
Thay thế ? với truy vấn con CHỌN AVG(lương) TỪ nhân viên — nó trả về một số duy nhất để sử dụng làm ngưỡng.
Giải pháp khả dụng sau 3 lần thử
Xem lại bài tập
Liệt kê tên (departments.name) của các phòng ban có ít nhất một nhân viên có mức lương lớn hơn 50000. Sử dụng truy vấn con có IN. Sắp xếp theo thứ tự bảng chữ cái.
Hiển thị gợi ý
Truy vấn con bên trong trả về id của các phòng ban có nhân viên có mức lương > 50000. Sau đó, WHERE id IN (...) trên truy vấn bên ngoài.
Giải pháp khả dụng sau 3 lần thử