Truy vấn dữ liệu – Câu truy vấn con

Câu truy vấn con
Câu truy vấn con

Câu truy vấn con (Subquery) là một câu truy vấn nằm trong một mệnh đề của câu truy vấn khác. Subquery có thể lồng trong một câu truy vấn SELECT, INSERT, UPDATEDELETE.

Tổng quan về subquery

Trước khi tìm hiểu về subquery, chúng ta hãy cùng nhau xem qua và thực thi 2 câu truy vấn sau đây:

2 câu truy vấn này, cho ra cùng một kết quả. Đối với những bạn học chuyên về CNTT, thì việc sử dụng các phương thức lồng nhau như trong câu truy vấn thứ 2 thật đơn giản đúng không. Tuy nhiên, để tường minh hơn, mình sẽ giải thích sơ qua nguyên lý.

Đối với những câu truy vấn có câu truy vấn con, hệ thống sẽ phân tích và đưa từng câu truy vấn vào ngăn xếp (stack). Hệ thống gặp câu truy vấn cha (lvl 1) đưa nó vào stack, khi phân thích câu truy vấn lvl 1, nó thấy câu truy vấn con (lvl 2) tiếp tục đưa lvl 2 vào stack.Cứ tiếp tục như vậy cho đến hết.

Ngăn xếp

Nguyên lý của stack là FILO (first in, last out), nghĩa là vào đầu tiên thì sẽ ra cuối cùng. Theo nguyên lý trên, thì câu truy vấn con nằm ở cấp lồng sau cùng sẽ được xử lý đầu tiên. Kết quả của câu truy vấn con sau khi được xử lý sẽ được lắp vào câu truy vấn tra để tiếp tục xử lý.

Các câu truy vấn của chúng ta có thể trả về một trong những trường hợp sau:

  • Một số – câu truy vấn con sử dụng các aggregate function
  • Một tập hợp khi chúng ta truy vấn 1 thuộc tính duy nhất
  • Danh sách dữ liệu – tương đương với 1 bảng khi chúng ta truy vấn nhiều thuộc tính hay sử dụng SELECT * để truy vấn tất cả

Tùy kết quả trả về của câu truy vấn con, chúng ta có thể sử dụng các toán tử so sánh hay (NOT) IN, (NOT) EXISTS để sử dụng kết quả này trong câu truy vấn cha. Để rõ hơn, các bạn có thể xem một số ví dụ ở phần cuối cùng.

Cú pháp của subquery

Câu truy vấn con có thể có các thành phần:

  • Mệnh đề SELECT
  • Mệnh đề FROM
  • Mệnh đề WHERE (có thể có hoặc không)
  • Mệnh đề GROUP BY (có thể có hoặc không)
  • Mệnh đề HAVING (có thể có hoặc không)

Câu truy vấn con sẽ được bao bằng một dấu ngoặc tròn “()”. Kết thúc câu truy vấn chúng ta không sử dụng dấu chấm phẩy “;”.

Một số dạng câu truy vấn con chúng ta thường gặp:

  • WHERE expression [NOT] IN (subquery)
  • WHERE expression comparison_operator [ANY | ALL] (subquery)
  • WHERE [NOT] EXISTS (subquery)

Một số luật khi sử dụng subquery

Câu truy vấn con sẽ phải tuân theo một số luật sau:

  • Subquery không hỗ trợ các thuộc tính có kiểu dữ liệu là text, ntext và image
  • Phương thức DISTINCT không thể sử dụng chung với mệnh đề GROUP BY
  • Các mệnh đề COMPUTE và INTO không thể sử dụng
  • Mệnh đề ODER BY chỉ có thể kết hợp với phương thức TOP

Các lưu ý khi sử dụng subquery

Tên đầy đủ và bí danh

Cũng tương tự khi sử dụng phương pháp liên kết nhiều bảng dữ liệu. Chúng ta có thể gặp những thuộc tính (cột dữ liệu) có cùng tên. Do đó, khi sử dụng subquery, cần phải thực hiện 2 việc:

  • Đặc tả tên đầy đủ (tên_bảng.tên_thuộc_tính)
  • Sử dụng bí danh (phương thức AS) giúp kết quả được tường minh hơn

Nhiều cấp độ lồng

Subquery cho phép chúng ta lồng tối đa 32 cấp độ. Tuy nhiên, con số 32 chỉ nằm trên lý thuyết vì sẽ có một số rào cản như:

  • Khả năng của chúng ta: các bạn có thể hình dung hay kiểm soát một câu truy vấn trong một câu truy vấn trong một câu truy vấn trong một câu truy vấn trong một ….
  • Giới hạn của phần cứng, hệ điều hành: như các bạn đã biết, các biến, tham số trong câu truy vấn sẽ được lưu trữ trên bộ nhớ, được CPU xử lý. Tùy theo phần cứng và kiến trúc của hệ điều hành. Các thông số về bộ nhớ được cấp phát cho mỗi chương trình là có giới hạn. Do đó, câu truy vấn của chúng ta cũng bị giới hạn (Ví dụ 32 câu truy vấn đơn giản, nhưng chỉ có thể 10 câu truy vấn có tính toán phức tạp).

Cân nhắc giữa subquery và join

Giữa 2 phương thức, sử dụng câu truy vấn conliên kết nhiều bảng dữ liệu có những ưu nhược điểm khác nhau. Chúng ta không thể khẳng định phương thức nào tối ưu hơn phương thức nào. Có thể các bạn sẽ dễ dàng tìm kiếm các bài viết khẳng định phương thức a tốt hơn phương thức b hay ngược lại. Tuy nhiên, hãy nhớ đó chỉ là quan điểm của tác giả. Nếu như có 1 phương thức vượt trội hơn thì chắc chắc chúng ta đã không có phương thức con lại.  Do đó, tùy trường hợp chúng ta sẽ chọn phương án của mình.

Một vài ví dụ

Ví dụ 1: Liệt kê tất cả hóa đơn, có giá trị lớn hơn giá trị trung bình.

Lúc này, câu truy vấn con sẽ trả về 1 giá trị. Chúng ta có thể sử dụng toán tử so sánh với kết quả trả về của nó.

Ví dụ 2: Ví dụ ở đầu bài viết, liệt kê các bài hát thuộc 2 album ‘Are You Experienced?’,’The Best Of Men At Work’ .

Trong trường hợp này, chúng ta có thể thấy kết quả trả về của câu truy vấn con bao gồm 1 danh sách với 2 giá trị [120, 147]. Do đó, chúng ta có thể đơn giản sử dụng toán tử IN để kiểm tra.