CodeGym /Các khóa học /SQL SELF /Subquery là gì và tại sao lại cần dùng nó?

Subquery là gì và tại sao lại cần dùng nó?

SQL SELF
Mức độ , Bài học
Có sẵn

Giờ bạn đã sẵn sàng cho bước tiếp theo — làm việc với subquery trong SQL rồi đấy. Hôm nay mình sẽ giải thích subquery là gì, tại sao lại cần, có những loại subquery nào và tại sao nó lại hữu ích ngoài đời thực.

Subquery (hay truy vấn lồng nhau) — là những câu truy vấn SQL được sử dụng bên trong các câu truy vấn SQL khác. Kiểu như búp bê matryoshka hoặc bắp cải ấy: có một truy vấn bên ngoài, bên trong nó lại có một truy vấn nhỏ hơn. Subquery sẽ chạy trước, và kết quả của nó sẽ được truy vấn bên ngoài (thường gọi là "chính") sử dụng.

Cùng xem ví dụ cho dễ hiểu nhé:

Ví dụ 1: Nó hoạt động như thế nào

Giả sử mình có bảng students với dữ liệu như sau:

id tên tuổi nhóm_id
1 Alysa 20 1
2 Bob 22 2
3 Klarc 21 1
4 Dina 23 3
5 Emilia 22 2

Và còn có bảng groups, lưu thông tin về tên các nhóm:

id tên_nhóm
1 Lop toan
2 Lop ly
3 Lop van

Nếu muốn biết tên các nhóm mà sinh viên đang học, mình có thể dùng subquery như sau:

SELECT tên_nhóm
FROM groups 
WHERE id IN (
    SELECT nhóm_id 
    FROM students 
    WHERE tuổi > 21
);

Chuyện gì xảy ra ở đây nhỉ?

Subquery:

SELECT nhóm_id 
FROM students 
WHERE tuổi > 21

Câu này sẽ lấy nhóm_id của tất cả sinh viên lớn hơn 21 tuổi. Kết quả: danh sách id nhóm, ví dụ [2, 3].

Truy vấn chính:

SELECT tên_nhóm 
FROM groups 
WHERE id IN ([kết quả subquery])

Câu này dùng kết quả của subquery và trả về tên các nhóm có id là 2 hoặc 3.

Kết quả:

Lop ly
Lop van

Vẫn chưa hiểu gì à? Bình thường thôi. Đừng lo, mình sẽ giải thích kỹ hơn ngay sau đây.

Bắt đầu từ ý đơn giản — kết quả của một câu SELECT — thực ra là một bảng ảo. Nó có cột, có dòng. Chẳng khác gì bảng thật cả, đúng không?

Mà nếu kết quả truy vấn là bảng, thì bạn có thể dùng nó ở những chỗ mà bảng thật cũng dùng được: trong JOIN chẳng hạn, hoặc trong các cấu trúc phức tạp hơn.

Nó không có tên, đó là vấn đề. Nhưng các cột-expression cũng không có tên, và mình giải quyết bằng cách đặt alias — bí danh cho nó. Bảng ảo cũng vậy, đặt alias là xong.

Chi tiết hơn sẽ có ở các bài sau — không spoil trước đâu :P

Lợi ích của subquery

  1. Giúp đơn giản hóa các bài toán phức tạp. Đôi khi một bảng không chứa đủ thông tin bạn cần lấy. Subquery cho phép chia truy vấn thành hai bước: đầu tiên lấy kết quả trung gian, sau đó dùng nó để lấy dữ liệu cuối cùng.

  2. Làm việc với kết quả trung gian. Subquery rất hữu ích khi bạn cần tính toán gì đó trước khi xử lý dữ liệu. Ví dụ, tìm giá trị nhỏ nhất hoặc tính tổng.

  3. Làm code dễ đọc hơn. Subquery giúp code có cấu trúc rõ ràng hơn, nhất là khi bạn làm với bảng lớn và logic phức tạp.

Các loại subquery cơ bản

Subquery có thể dùng ở nhiều chỗ khác nhau trong câu SQL. Tùy vào vị trí bạn viết, nó sẽ chia thành vài loại.

  1. Subquery trong SELECT. Subquery nằm trong danh sách cột và dùng để tính giá trị. Rất tiện nếu bạn muốn thêm cột mới vào kết quả.

Ví dụ — thêm cột tuổi lớn nhất trong số sinh viên:

SELECT tên, tuổi,
       (SELECT MAX(tuổi) FROM students) AS tuổi_lớn_nhất 
FROM students;

Kết quả:

tên tuổi tuổi_lớn_nhất
Alysa 20 23
Bob 22 23
Klarc 21 23
Dina 23 23
Emilia 22 23
  1. Subquery trong FROM. Subquery được dùng như bảng tạm thời. Rất hữu ích nếu bạn cần tổng hợp hoặc biến đổi dữ liệu trước.

Ví dụ — tính tuổi trung bình của sinh viên trong từng nhóm:

SELECT tmp.nhóm_id, tmp.tuổi_trung_bình
FROM (
    SELECT nhóm_id, AVG(tuổi) AS tuổi_trung_bình
    FROM students
    GROUP BY nhóm_id
) AS tmp -- Đặt alias tmp cho bảng tạm 
WHERE tmp.tuổi_trung_bình > 21;

Kết quả:

nhóm_id tuổi_trung_bình
2 22.0
3 23.0
  1. Subquery trong WHEREHAVING. Subquery có thể là điều kiện để lọc dòng. Thường dùng để kiểm tra
  2. sự tồn tại của bản ghi hoặc so sánh giá trị.

Ví dụ — sinh viên nào lớn hơn tuổi trung bình:

SELECT tên, tuổi
FROM students
WHERE tuổi > (
    SELECT AVG(tuổi) 
    FROM students
);

Kết quả:

tên tuổi
Bob 22
Dina 23
Emilia 22

Ưu điểm khi dùng subquery

Tăng độ linh hoạt: subquery cho phép bạn xử lý các cấu trúc dữ liệu phức tạp hơn.

Chia nhỏ bài toán: logic có thể chia thành các subquery, làm code dễ đọc hơn.

Truy cập dữ liệu trung gian: bạn có thể xử lý dữ liệu "trên đường đi", không cần tạo bảng tạm trong database.

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION