Truy vấn dữ liệu – Mệnh đề WHERE

Mệnh đề WHERE trong câu truy vấn
Mệnh đề WHERE trong câu truy vấn

Tiếp tục về loạt bài truy vấn dữ liệu. Trong bài viết này, chúng ta sẽ tìm hiểu mệnh đề thứ 3 trong câu truy vấn – mệnh đề WHERE.

Mệnh đề WHERE trong câu truy vấn được dùng để đặc tả điều kiện tìm kiếm (lọc) dữ liệu.

Cú Pháp

Với điều kiện tìm kiếm (search_condition) là một mệnh đề logic.

Toán tử so sánh

Trong T-SQL chúng ta có các toán tử so sánh sau:

Toán tử Ý nghĩa
= (Equals) So sánh bằng
> (Greater Than) So sánh lớn hơn
< (Less Than) So sánh nhỏ hơn
>= (Greate Than or Equal To) So sánh lớn hơn hoặc bằng
<= (Less Than or Equal To) So sánh nhỏ hơn hoặc bằng
<> (Not Equal To) So sánh khác
!= (Not Equal To) So sánh khác (Không theo chuẩn ISO)
!< (Not Less Than) Không nhỏ hơn (Không theo chuẩn ISO)
!> (Not Greater Than) Không lớn hơn (Không theo chuẩn ISO)

Chúng ta có thể sử dụng các toán tử so sánh trên, để so sánh 2 đối tượng, 2 giá trị cùng kiểu dữ liệu. Ví dụ: kiểu số so với kiểu số, ngày tháng so với ngày tháng.

Khi sử dụng toán tử so sánh có một vài điều cần chú ý:

  • Số thực còn được gọi là kiểu dữ liệu số gần đúng/xấp sỉ (Approximate-number). Vì chúng ta không thể biểu diễn các số vô tỉ một cách chính xác được. Do đó, khi so sánh các giá trị số thực cần phải cẩn thận.
  • Hạn chế sử dụng các toản tử không theo chuẩn ISO. Vì biết đâu, một ngày nào đó, bạn sẽ làm việc trên một hệ thống mà nó không hỗ các toán tử không theo chuẩn.

Dưới đây là một vài ví dụ về sử dụng toán tử so sánh trong mệnh đề WHERE. Các bạn có thể copy và thực thi xem kết quả thử.

Toán tử LIKE

Khi làm việc với chuỗi, có những trường hợp các toán tử so sánh phía trên không thể giúp chúng ta được.

Ví dụ: Hôm nay ở trường, mình lướt ngang một cô gái rất xinh. Mình muốn tìm thông tin về cô gái ấy. Nhưng mình chỉ kịp liếc được tên cô gái ấy bắt đầu bằng chữ ‘Nh’.

Rõ ràng, chúng ta không đủ thông tin để có thể lọc dữ liệu bằng các toán tử so sánh phía trên được. May mắn, T-SQL cung cấp cho chúng ta phương thức LIKE. Nó cho phép chúng ta tìm kiếm một chuỗi theo mẫu.

Để xây dựng một mẫu, chúng ta có một số ký tự đặc biệt:

Ký tự Mô tả
% Đại diện cho một chuỗi ký tự, có thể rỗng hoặc có chiều dài bất ký
_ (gạch dưới, underscore) Đại diện cho một ký tự bất kỳ
[] Đại diện cho 1 trong các phần tử của tập các ký tự bên trong
[^] Đại diện cho 1 ký tự không thuộc tập ký tự chứa bên trong

Rất tiếc là mình không có CSDL trường học giống như trong ví dụ phía trên. Do đó, mình sẽ cung cấp cho các bạn một vài ví dụ làm việc với phương thức LIKE trong CSDL chinook của chúng ta.

Các bạn hãy thử copy và thực thi thử các ví dụ phía trên của mình. Sau đó, thử tìm kiếm một vài dữ liệu bằng mẫu của các bạn.

Toán tử IN

Phương thức IN cho phép chúng ta kiểm tra một phần tử có thuộc một tập hợp hay không. Phương thức IN rất hữu dụng, có thể sử dụng thay thế cho nhiều mệnh đề OR kết hợp.

Ví dụ: Mình có một khảo sát nhỏ về ngày học CSDL. Mình có thể sử dụng 1 trong 2 cách sau:

  • Các bạn có thể học môn CSDL vào thứ hai hoặc thứ ba hoặc thứ bảy.
  • Các bạn có thể học môn CSDL một trong những ngày sau: thứ hai, thứ ba, thứ bảy.

Bây giờ ví dụ trực tiếp trên CSDL chinook của chúng ta. Chúng ta sẽ liệt kê các track thuộc thể loại Alternative hoặc Classical hoặc Opera. Do chưa tới phần liên kết các bảng nên chúng ta sẽ làm hơi thủ công một xíu. Mở bảng Genre lên và thấy được giá trị GenreId của 3 thể loại này là 23, 24 và 25. Vậy câu truy vấn của chúng ta sẽ là.

Hoặc áp dụng phương thức IN chúng ta có:

Câu truy vấn trên sẽ lọc các track có giá trị GenreId là phần tử của tập hợp (23, 24, 25). Kết quả trả về sẽ tương tự câu truy vấn OR nhưng ngắn và tường minh hơn. Nếu chúng ta có nhiều giá trị hơn nữa, phương thức IN sẽ có rất nhiều ưu điểm phải không nào.

Toán tử BETWEEN

Để biết một giá trị có nằm trong một đoạn hay không (ví dụ biến x có nằm trong đoạn[3, 10] hay 1 ngày y nào đó có nằm trong nửa đầu tháng 3 năm 2020 [01/03/2020 – 15/03/2020]), chúng ta có thể dễ dàng kiểm tra bằng cách kết hợp các toán tử so sánh.

Ví dụ: Tìm tất cả hóa đơn trong quý 1 năm 2012

Tuy nhiên, T-SQL hỗ trợ cho chúng ta phương thức BETWEEN để rút gọn câu truy vấn và tăng tính ngữ nghĩa cho câu truy vấn của chsung ta. Với BETWEEN, chúng ta có thể rút gọn câu truy vấn phía trên thành:

Bạn hãy copy và thực thi thử cả 2 câu truy vấn trên. Kiểm tra xem chúng có ra kết quả giống nhau không. Sau đó thử tìm tất cả các track có thời gian từ 100 000 đến 200 000 milliseconds nha.

Giá trị NULL

NULL là một giá trị khá đặc biệt trong các ngôn ngữ lập trình nói chung và T-SQL nói riêng. Chúng ta có thể hiểu đơn giản NULL có nghĩa là không có giá trị. Bởi nó không có giá trị, nên ta không thể sử dụng các toán tử so sánh, các phương thức LIKE hay IN để làm việc với nó.

Chúng ta chỉ có thể kiểm tra một giá trị có rỗng hay không. Để kiểm tra vấn đề này, chúng ta có phương thức IS.

Chúng ta có thể sử dụng cú pháp IS NULL để kiểm tra một giá trị có rỗng hay không hoặc ngược lại IS NOT NULL để kiểm tra một giá trị khác rỗng hay không.

Ví dụ, trong bảng Employee, chúng ta sẽ thử tìm kiếm ai là người chức to nhất. Các bạn để ý thuộc tính ReportsTo. Vậy theo suy đoán của mình, nhân viên không phải báo cáo (report) cho ai thì người đó có chức bự nhất. Và thuộc tính ReportsTo sẽ có giá trị NULL

Các bạn thử kiểm tra xem. Người này là ai và anh/cô ấy có chức vụ gì.

Kết hợp nhiều điều kiện

Trong thực tế, chúng ta thường kết hợp nhiều điều kiện để tìm kiếm dữ liệu. T-SQL cho phép chúng ta sử dụng 3 toán tử logic là: AND, OR và NOT để kết hợp các mệnh đề logic lại với nhau.

Ví dụ: Mình muốn liệt kê tất cả các khách hàng theo điều kiện: Đến từ ‘USA’ hoặc ‘Canada’ và được hỗ trợ bởi nhân viên có Id = 3. Dưới đây là câu truy vấn của mình.

Và đây là kết quả:

Kết quả truy vấn
Kết quả truy vấn

Có gì đó không ổn, trong kết quả của chúng ta, xuất hiện cả những khách hàng được hỗ trợ bởi nhân viên 4 và 5. Tại sao????

Để giải thích cho kết quả này, trước hết chúng ta xem lại bài một số khái niệm, thuật ngữ. Các bạn sẽ tìm thấy một khái niệm là độ ưu tiên của các toán tử, dựa vào link tham khảo chúng ta có thứ tự thực hiện các toán tử như sau: AND -> OR

Do đó, lúc này mệnh đề của chúng ta trở thành: Các khách đến từ ‘Canada’ được hỗ trợ bởi nhân viên có Id = 3 hoặc các khách hàng đến từ ‘USA’. So với kết quả thì rất đúng cho mệnh đề này.

Vậy để khắc phục vấn đề này chúng ta sẽ sử dụng đấu ngoặc tròn ‘()’. Để tăng độ ưu tiên cho toán tử OR.

Và kết quả lúc này là:

Kết quả truy vấn
Kết quả truy vấn

Đã hợp lý và đúng với yêu cầu của chúng ta ban đầu.

Vậy khi kết hợp nhiều toán tử chúng ta cần phải nắm rõ độ ưu tiên của các toán tử và các phép toán logic cơ bản.