Tìm kiếm với câu lệnh nâng cao

Một phần của tài liệu TÀI LIỆU DẠY HỌC CƠ SỞ DỮ LIỆU (Trang 95 - 100)

3.3. C ÁC THAO TÁC DỮ LIỆU TRONG SQL

3.3.2. Tìm kiếm với câu lệnh nâng cao

a. Thứ tự hiển thị các bản ghi - Mệnh đề ORDER BY

Trong ví dụ 3.33 và 3.34 ta thấy các sinh viên không được sắp xếp theo lớp hay không theo thứ tự tăng hay giảm dần của năm sinh. Để thực hiện được các điều trên, SQL hỗ trợ bởi mệnh đề ORDER BY để sắp xếp kết quả tìm được. Cú pháp mệnh đề này là:

ORDER BY <tên cột>|<biểu thức>[ASC|DESC], <tên cột> ,<tên cột>|<biểu thức>[ASC| DESC], ...

Biểu thức phải có giá trị số; nó thể hiện số thứ tự của cột trong bảng kết quả được chỉ định phải sắp xếp thứ tự thay vì phải chỉ rõ tên cột, hơn nữa nếu cột kết quả là cột tính toán thì nó chưa có tên nên các sử dụng biểu thức là một biện pháp thay thế hữu dụng. Có thể sắp xếp theo thứ tự tăng dần (với từ khóa ASC - Viết tắt của ASCending - mặc định là ASC) hoặc giảm dần (DESCending) theo giá trị cột. Trước hết các bản ghi được xếp theo thứ tự của cột thứ nhất; các bản ghi có cùng giá trị ở cột 1 sẽ được sắp xếp theo thứ tự cột thứ 2, các bản ghi có cùng giá trị ở cả 2 cột 1 và 2 sẽ được xếp theo cột thứ 3,...

Ví dụ 3.35. Lập danh sách các sinh viên quê ở “Thanh Hoá” hoặc “Nghệ An”, sắp xếp danh sách theo thứ tự giảm dần của năm sinh và tăng dần của họ tên.

SELECT *

FROM SINH_VIEN

WHERE (QueQuan = “Thanh Hoá”) OR (QueQuan = “Nghệ An”);

ORDER BY HoTenSV, NamSinh DESC;

Vì thứ tự trong bảng SINH_VIEN của cột HoTenSV là thứ 2, cột NamSinh là thứ 3 nên có thể viết

SELECT *

FROM SINH_VIEN

WHERE (QueQuan = “Thanh Hoá”) OR (QueQuan = “Nghệ An”);

ORDER BY 2 ASC, 3 DESC;

b. Điều kiện hiển thị các bản ghi - Mệnh đề GROUP BY HAVING

Khi sử dụng mệnh đề GROUP BY, mỗi giá trị của mục được liệt kê ngay sau từ khoá SELECT là một giá trị cho một nhóm. Danh sách các mục đứng ngay sau từ khoá SELECT có thể là:

• các tên cột

• các hàm gộp

• các hằng

• một biểu thức chứa tổ hợp của những mục trên

96

Lưu ý: tất cả tên cột xuất hiện trong danh sách sau từ khoá SELECT đều phải có mặt trong câu GROUP BY chỉ trừ những tên cột có trong khai báo hàm gộp.

Ví dụ 3.36. Tìm năm sinh nhỏ nhất của từng lớp SELECT MaLop, MIN (NamSinh)

FROM SINH_VIEN

GROUP BY MaLop;

Trường hợp không muốn áp dụng hàm gộp cho mọi nhóm theo tác động của GROUP BY mà chỉ áp dụng cho một số nhóm thoả một điều kiện nào đó, SQL cung cấp từ khoá HAVING nhằm mục đích này. Điều kiện chọn các nhóm sẽ được áp dụng hàm gộp được viết trong câu HAVING

Ví dụ 3.37. Tìm năm sinh nhỏ nhất của từng lớp, với điều kiện năm sinh nhỏ nhất đó phải nhỏ hơn năm 1995

SELECT MaLop, MIN (NamSinh)

FROM SINH_VIEN

GROUP BY MaLop

HAVING MIN (NamSinh)<1995;

Cần phân biệt mục đích của câu WHERE và câu HAVING

• câu WHERE lọc lấy một số bộ nào đó trong một bảng để đưa vào kết quả

• câu HAVING lọc lấy một số nhóm nào đó để đưa vào bảng kết quả.

• các tên cột dùng trong câu HAVING cũng phải có mặt trong danh sách tên cột ở câu GROUP BY hoặc trong một hàm gộp, nếu không thì điều kiện này chuyển vào câu WHERE (Lưu ý: hàm gộp không được dùng trong câu WHERE).

• nếu câu truy vấn có cả câu WHERE và câu HAVING, thì o điều kiện chọn ở câu WHERE được áp dụng.

o các bộ thoả điều kiện ở câu WHERE được tạo thành các nhóm do câu GROUP BY.

o tiếp theo, câu HAVING loại đi những nhóm không thoả điều kiện đặt sau từ HAVING.

o các nhóm còn lại được câu SELECT sử dụng để tạo ra các bộ là kết quả của câu truy vấn.

c. Truy vấn thông tin từ nhiều bảng dữ liệu.

Việc thực hiện các câu truy vấn trên nhiều bảng, về bản chất là giống như trên một bảng, tức là cần chỉ ra thông tin gì cần tìm và lấy từ các nguồn dữ liệu nào. Các bảng dữ liệu nguồn này cần chỉ ra trong mệnh đề FROM trong câu lệnh SELECT.

Nếu các bảng dữ liệu nguồn có các tên thuộc tính giống nhau thì tên thuộc tính này phải được viết tường minh trong biểu thức tìm kiếm với tên bảng đi kèm phía trước. Nói chung trong một CSDL quan hệ, các bảng thường có các mối liên hệ với nhau. Các bảng được liên hệ với nhau thông qua phép kết nối và thường là kết nối bằng (Equi-Join). Mối liên hệ phải được thể hiện trong phép kết nối của mệnh đề

97

FROM hoặc thông qua điều kiện của mệnh đề WHERE của câu lệnh SELECT. Nếu không thể hiện mối liên hệ này, kết quả sẽ là bảng tích Descartes của 2 bảng.

Ví dụ 3.38. Lập danh sách sinh viên của từng lớp, danh sách gồm các thông tin:

mã sinh viên, họ tên sinh viên, tên lớp.

Trong câu hỏi này, TenLop được lấy từ bảng LOP, MaSV, HoTenSV được lấy từ bảng SINH_VIEN. Hai bảng này được kết nối với nhau thông qua giá trị của thuộc tính MaLop.

Một điểm nữa cần chú ý là thuộc tính MaLop có trong cả 2 bảng SINH_VIEN và LOP, do đó khi viết lệnh phải chỉ rõ MaLop của bảng nào (mặc dù chúng là như nhau)

SELECT MaSV, HoTenSV, TenLop FROM LOP, SINH_VIEN

WHERE SINH_VIEN.MaLop=LOP.MaLop;

Hoặc có thể viết cách khác nhờ sử dụng phép kết nối bằng INNER JOIN như sau:

SELECT MaSV, HoTenSV, TenLop FROM LOP INNER JOIN SINH_VIEN ON (SINH_VIEN.MaLop=LOP.MaLop);

Để giảm nhẹ công việc phải viết tên bảng nhiều lần trong lệnh, SQL hỗ trợ tên bí danh cho bảng bằng cách đặt bí danh ngay sau tên bảng nguồn. Bí danh này có thể được dùng trước khi nó được đặt. Dạng đầu tiên của ví dụ 3.38 được viết lại tương đương như sau:

SELECT MaSV, HoTenSV, TenLop FROM LOP, SINH_VIEN SV WHERE SV.MaLop=LOP.MaLop;

d. Các câu truy vấn lồng nhau (Query with SubQuery)

Trong nhiều trường hợp, ta cần phải tìm kiếm thông tin qua nhiều bước: kết quả của bước trước được sử dụng trong biểu thức của câu truy vấn tiếp theo, rồi kết quả của câu truy vấn này lại được dùng trong biểu thức của câu truy vấn tiếp theo nữa v.v...

Bằng ngôn ngữ thủ tục, qua mỗi bước ta phải ghi nhớ lại các kết quả trung gian này.

Nếu như vậy thì công việc truy vấn dữ liệu sẽ rất vất vả cho những người thao tác trực tiếp với CSDL. SQL - SELECT cho phép lấy ngay kết quả của một câu truy vấn để xây dựng biều thức điều kiện cho một câu hỏi khác. Câu hỏi trung gian đó được gọi là câu hỏi con (SubQuery). Câu hỏi con phải được bao trong cặp dấu ngoặc tròn trong biểu thức của câu hỏi chính. Sự cho phép câu hỏi con là một trong những ưu điểm nổi bật của ngôn ngữ quản trị CSDL quan hệ.

Ví dụ 3.39. Lập danh sách các sinh viên cùng lớp với sinh viên “Lê Thị Hà”.

Phân tích câu hỏi này ta có 2 bước:

Bước 1: Tìm mã lớp (mà) sinh viên “Lê Thị Hà” học (giả sử lớp tìm được có mã là pp).

Bước 2: Tìm những sinh viên có mã lớp bằng pp

98

Câu hỏi ở bước 1 là câu hỏi con cho câu hỏi ở bước 2. Câu lệnh SQL như sau:

SELECT *

FROM SINH_VIEN WHERE MaLop = ANY

(SELECT MaLop FROM SINH_VIEN

WHERE HoTenSV = “Lê Thị Hà”);

Ví dụ 3.40. Lập danh sách các sinh viên học lớp “ĐH CNTT K16”, danh sách gồm mã sinh viên, họ tên sinh viên, giới tính.

Câu hỏi này phải được thực hiện qua 2 bước:

Bước 1: Tìm mã lớp của lớp có tên là “ĐH CNTT K16” (mã pp).

Bước 2: Tìm mã sinh viên, họ tên sinh viên, giới tính của các sinh viên học lớp có mã pp.

Như vậy ta phải viết 2 câu hỏi con lồng nhau trong một câu hỏi chính:

SELECT MaSV, HoTenSV, GioiTinh FROM SINH_VIEN

WHERE MaLop = ANY (SELECT MaLop

FROM LOP

WHERE TenLop = “ĐH CNTT K16”);

Ví dụ 3.41. Lập danh sách các sinh viên học khoa “CNTT&TT”, danh sách gồm mã sinh viên, họ tên sinh viên, giới tính.

Câu hỏi này phải được thực hiện qua 3 bước:

Bước 1: Tìm mã khoa của khoa có tên là “CNTT&TT” (mã pp).

Bước 2: Tìm mã lớp của các lớp có mã khoa là pp ( ll)

Bước 3: Tìm mã sinh viên, họ tên sinh viên, giới tính của các sinh viên học lớp có mã ll.

Như vậy, ta phải viết 3 câu hỏi con lồng nhau trong một câu hỏi chính:

SELECT MaSV, HoTenSV, GioiTinh FROM SINH_VIEN

WHERE MaLop = ANY (SELECT MaLop

FROM LOP

WHERE MaLop = ANY (SELECT MaKhoa

FROM KHOA

WHERE TenKhoa = “CNTT&TT”);

Kết quả của câu hỏi con được sử dụng trong phép so sánh với một giá trị khác trong biểu thức điều kiện của câu hỏi bao nó. Các phép so sánh có dạng:

99

<phép so sánh>[<lượng từ>] (SELECT - câu hỏi con) Ở đây :

<Phép so sánh> có thể là các phép so sánh số học (>, ≥, <, ≤, <>, =) hoặc phép toán tập hợp IN, LIKE hoặc NOT LIKE.

• <Lượng từ> có thể là ALL, ANY (hoặc SOME). Phép so sánh = ANY có thể được thay tương đương bằng phép toán IN; phép so sánh <> ALL có thể thay tương đương bằng phép toán NOT IN.

SQL không cho phép dùng hàm hợp của các hàm gộp kiểu như MIN (AVG (...)) Ví dụ 3.42. Lập danh sách các sinh viên nhiều tuổi hơn sinh viên nhiều tuổi nhất của lớp “ĐH CNTT K16”.

Câu hỏi được thực hiện

Bước 1: Tìm Mã lớp của lớp có tên là “ĐH CNTT K16” (mãpp).

Bước 2: Tạo nhóm sinh viên có mã lớp là pp và tìm sinh viên nhiều tuổi nhất của nhóm (nn)

Bước 2: Tìm mã sinh viên, họ tên sinh viên, giới tính của các sinh viên có năm sinh lớn hơn nn.

Như vậy, ta phải viết 3 câu hỏi con lồng nhau trong một câu hỏi chính:

SELECT MaSV, HoTenSV, GioiTinh FROM SINH_VIEN

WHERE NamSinh ≤ ALL (SELECT MIN(NamSinh) FROM SINH_VIEN WHERE MaLop = ANY

(SELECT MaLop

FROM LOP

WHERE TenLop = “ĐH CNTT K16”));

Từ khoá EXIST và NOT EXIST trong SQL cũng chỉ được sử dụng với các truy vấn con. Các truy vấn con này sẽ đưa ra kết quả là một trong hai giá trị TRUE và FALSE.

EXIST (<truy vấn con>) có giá trị TRUE nếu kết quả của (<truy vấn con>) khác rỗng và có giá trị FALSE trong trường hợp ngược lại.

Truy vấn con đi kèm với EXIST (hay NOT EXIST) dùng để kiểm tra một tập rỗng hay không nên bảng kết quả của truy vấn con này có thể có hơn một cột.

Dùng NOT EXIST cho một truy vấn con sẽ cho giá trị ngược lại với việc dùng EXIST cho truy vấn con này.

Ví dụ 3.43. Đưa ra danh sách các lớp của khoa CNTT&TT SELECT *

FROM LOP

WHERE EXIST

100 (SELECT *

FROM KHOA

WHERE KHOA.MaKhoa = LOP.MaKhoa AND TenKhoa= “CNTT&TT”);

Một phần của tài liệu TÀI LIỆU DẠY HỌC CƠ SỞ DỮ LIỆU (Trang 95 - 100)

Tải bản đầy đủ (PDF)

(188 trang)