Trong SQL để khai thác, tìm kiếm, trích rút dữ liệu (truy vấn) từ một cơ sở dữ liệu ta sử dụng câu lệnh có cấu trúc khối cơ bản có dạng
FROM... WHERE...
hay còn gọi là câu lệnh truy vấn. Kết quả trả về của câu lệnh truy vấn là một bảng. Cấu trúc khối đầy đủ là khá phức tạp, tuy nhiên cấu trúc cơ bản của nó lại tương đối đơn giản.
Trong đó:
+ Mệnh đề SELECT ... : Được dùng để liệt kê các cột cần đưa ra trong bảng kết quả. Mệnh đề này có vai trò như phép chiếu trong đại số quan hệ.
+ Mệnh đề FROM... : Được dùng để liệt kê các bảng cần truy nhập để lấy kết quả. Mệnh đề này có vai trò như phép tích đề các.
+ Mệnh đề WHERE: Mệnh đề này tương tự như phép chọn trong đại số quan hệ, được dùng để đặt điều kiện cho các bộ sẽ đưa ra trong bảng kết quả hoặc điều kiện liên kết các bảng.
Để làm rõ ý nghĩa của câu lệnh, ta có thể so sánh một khối với một biểu thức đại số quan hệ:
Câu lệnh
SELECT A1, A2, ...,An
FROM r1, r2, ..., rm
WHERE P
tương đương với biểu thức đại số quan hệ sau:
∏{A1, A2, ..., An}(σP (r1 x r2 x ... x rm))
Cấu trúc đầy đủ của khối SELECT:
SELECT [DISTINCT] * | <Danh_sách_cột> |<Danh_sách_biểu_thức>
FROM <Danh_sách_bảng> | <Danh_sách_View> [WHERE <Điều_kiện>]
[GROUP BY <Danh_sách_cột> [HAVING <Điều_kiện 1>]] [ORDER BY <Tên_cột> | <Biểu_thức > [ASC|DESC>]] [UNION | INTERSECT | MINUS <Khối_SELECT>]
Trong đó:
Mệnh đề SELECT ... : Được dùng để liệt kê các cột cần đưa ra trong bảng kết quả.
+ DISTINCT dùng để chỉ rằng trong bảng kết quả không có các bản ghi trùng nhau.
+ Các lựa chọn đưa ra trong bảng kết quả: Dấu *: Tất cả các cột
<Danh_sách_cột>: Các cột trong danh sách được đưa ra trong bảng kết quả, các cột viết cách nhau dấu phẩy.
<Danh_sách_biểu_thức>: Các biểu thức trong danh sách được đưa ra trong kết quả.
Mệnh đề FROM...Được dùng để liệt kê các bảng, các VIEW cần truy nhập để lấy kết quả. Giữa các bảng, các VIEW viết cách nhau dấu phẩy.
Mệnh đề WHERE...: Để xác định các bản ghi thỏa mãn điều kiện để đưa ra trong bảng kết quả hoặc điều kiện kết nối các bảng.
GROUP BY <Danh_sách_cột>: Nhóm các bản ghi thành nhóm theo các cột trong Danh_sách_cột.
[HAVING <Biểu_thức>]: Đặt điều kiện cho các nhóm sẽ được đưa ra trong bảng kết quả. Vì vậy, nó chỉ có khi có GROUP BY
ORDER BY <Danh_sách_cột> | <Biểu_thức> [ASC|DESC>]: Sắp xếp kết quả theo thứ tự tăng dần nếu dùng ASC, giảm dần nếu dùng DESC.
UNION|INTERSECT| MINUS <Khối_SELECT>: Như ta đã biết mỗi khối SELECT cho ta một bảng, do đó nó có thể được hợp, giao hay trừ cho một bảng khác đươc xác định bởi <Khối_SELECT>
Nhắc lại rằng, biểu thức báo gồm các phép toán tác động lên các toán hạng. Trong đó:
+ Các phép toán bao gồm:
Các phép toán số học: ^, *, /, Mod, +, – Các phép toán logic: Not, And, Or
Các phép toán tập hợp: Union, Intersect, Minus, Contain, in Các phép toán so sánh: =, >, >=, <, <=, <>
Các phép toán khác: BETWEEN, LIKE, EXISTS
+ Các toán hạng bao gồm hằng, tên cột, hàm, biểu thức. Sau đây là một số hàm thông dụng:
SUM(Tên_cột): Tính tổng các giá trị trong cột có tên là Tên_cột MAX(Tên_cột): Cho giá tri lớn nhất trong cột có tên là Tên_cột MIN(Tên_cột): Cho giá tri bé nhất trong cột có tên là Tên_cột COUNT(*|Tên_cột|DISTINCT Tên_cột): Đếm số bản ghi trong bảng theo tùy chọn:
Ký tự *: Đếm tất cả các bản ghi trong cột
Tên_cột: Đếm số bản ghi có giá trị cột khác NULL
DISTINCT Tên_cột: Đếm số bản ghi có giá trị cột khác NULL, các bản ghi có giá trị của cột giống nhau chỉ tính một.
Chú ý: Thứ tự thực hiện câu lệnh truy vấn như sau:
FROM → WHERE → GROUP BY → HAVING → SELECT →
ORDER BY
Để tìm hiểu câu lệnh truy vấn, chúng tôi tách câu lệnh tổng quát thành các dạng sau:
a) Truy vấn theo câu hỏi đơn giản.
Ở đây ta xem các câu hỏi đơn giản là các câu hỏi chỉ truy vấn trên một bảng. Đối với loại truy vấn này ta có thể xét các trường hợp sau:
* Truy vấn không điều kiện. Đây là dạng đơn giản nhất, chỉ có hai thành phần là SELECT và FROM.
Ví dụ: Đưa ra mã, tên của tất cả các mặt hàng trong CSDL BANHANG
SELECT MaMH, TenMH FROM MATHANG
Ví dụ: Đưa ra các địa danh có các khách hàng (DchiKH) của cửa hàng.
SELECT DISTINCT DChiKH FROM KHACHHANG
Ví dụ: Cho xem thông tin về tất cả các nhà cung cấp SELECT *
FROM NHACC
* Truy vấn có điều kiện
Ví dụ: Cho xem thông tin các khách hàng có địa chỉ ở “Hà Nội” SELECT *
FROM KHACHHANG WHERE DChiKH=”Hà Nội”
Ví dụ: Cho tên, số điện thoại của các khách hàng có địa chỉ ở “Hà Nội” và các khách hàng có địa chỉ ở “Nghệ An”
SELECT TenKH, DthoaiKH FROM KHACHHANG WHERE (DChiKH=”Hà Nội”) or (DChiKH=”Nghệ An”) * Truy vấn có xử lý xâu ký tự
Khi cần truy vấn có xử lý xâu ký tự, ta có thể sử dụng: Hằng xâu ký tự được đặt trong cặp dấu nháy kép “ ”
Ký tự %: Thay thế cho một xâu ký tự con
Khí tự _ : Thay thế cho một ký tự bất kỳ tại vị trí của _ Toán tử LIKE: Dùng để xử lý các xâu ký tự gần đúng Ví dụ: Cho xem thông tin về khách hàng có tên “Trần Anh”
SELECT *
FROM KHACHHANG WHERE TenKH=”Trần Anh”
Ví dụ: Cho xem thông tin về những khách hàng có tên là “Anh” SELECT *
FROM KHACHHANG
WHERE TenKH LIKE ”% Anh”
Ví dụ: Cho xem thông tin về những khách hàng có tên là Minh hay Ninh gì đó, nghĩa là tên có dạng “_inh”
SELECT *
FROM KHACHHANG
WHERE TenKH LIKE ”% _inh” * Truy vấn có sử dụng ngày tháng
Khi truy vấn có sử dụng ngày tháng cần lưu ý kiểu ngày tháng được viết ‘yyyy/mm/dd’. Tuy nhiên trong các hệ quản trị CSDL cụ thể quy cách này có thể được thiết lập khác.
Ví dụ: Cho xem mã của các khách hàng đã mua hàng trong ngày '30/04/2008'.
SELECT MaKH FROM HOADON
WHERE NgayHD=’2008/04/30’ * Truy vấn có sử dụng BETWEEN
Toán tử BETWEEN dùng để kiểm tra một giá trị có nằm trong một khoảng được xác định bởi một giá trị đầu và một giá trị cuối không. Cách sử dụng toán tử BETWEEN:
n BETWEEN n1 AND n2
Kết quả cho giá trị đúng nếu n1 ≤ n ≤ n2.
Ví dụ: Cho xem các số hóa đơn trên đó có ít nhất một mặt hàng có giá từ 100000 đến 200000
SELECT Distinct SoHD FROM HD_MH
WHERE DonGia BETWEEN 100000 AND 200000 * Truy vấn có sắp xếp
Trong câu lệnh truy vấn của SQL, ta có thể sắp xếp kết quả thu được bằng cách sử dụng mệnh đề ORDER.
Ví dụ: Xem thông tin của tất cả các mặt hàng theo thứ tự tăng dần của mã mặt hàng.
SELECT *
FROM MATHANG ORDER BY MaMH ASC
Ví dụ: Cho xem các số hóa đơn trên đó có mặt hàng mã “HPCOP” theo thứ tự giảm dần của số lượng
SELECT * FROM HD_MH
WHERE MaMH=”HPCOP” ORDER BY Soluong DESC
* Truy vấn có sử dụng GROUP và HAVING
Trong câu lệnh truy vấn của SQL, khi cần xử lý nhóm ta sử dụng mệnh đề GROUP. Để đặt điều kiện cho các nhóm ta sử dụng mệnh đề HAVING.
Ví dụ: Cho biết mã của từng nhà cung cấp và số lượng mặt hàng mà nhà cung cấp đó đã cung cấp.
SELECT MaNCC, COUNT(Distinct MaMH) FROM MH_NCC
GROUP BY MaNCC
Ví dụ: Cho biết mã của các nhà cung cấp đã cung cấp từ 5 mặt hàng trở lên.
SELECT MaNCC FROM MH_NCC GROUP BY MaNCC
HAVING Count(Distinct MaMH)>=5
* Truy vấn có sử dụng phép đổi tên
SQL cho phép ta có thể đổi tên quan hệ, tên thuộc tính trong câu lệnh truy vấn bằng việc sử dụng mệnh đề AS vói cú pháp như sau:
<Tên_cũ> AS <Tên_mới>
Ví dụ: Đưa ra mã, tên, địa chỉ của tất cả các khách hàng với việc đổi tên các cột TenKH, DiachiKH thành Ho_ten, Dia_chi.
SELECT MaKH, TenKH AS Ho_ten, DChiKH AS Dia_chi
FROM KHACHHANG
Ví dụ: Đưa ra mã, tên, điện thoại của tất cả các khách hàng có địa chỉ ở “Hà Nội” với việc đổi tên các cột TenKH, DThoạiKH thành Ho_ten, Dien_thoai và đổi tên bảng Khachhang thanh KH
SELECT MaKH, TenKH AS Ho_ten, DThoaiKH AS Dien_thoai FROM KHACHHANG AS KH
WHERE DChiKH=”Hà Nội” b) Truy vấn theo câu hỏi phức tạp.
Ta xem các câu hỏi phức tạp là các câu hỏi truy vấn trên nhiều bảng. Đối với loại truy vấn này ta có thể sử dụng hai cách sau:
* Sử dụng phép kết nối
Trong phần đại số quan hệ ta đã tìm hiểu phép kết nối. Ở đây ta sẽ tìm hiểu về cách sử dụng phép kết nối trong các câu lệnh truy vấn.
Khi kết nối hai bảng trong câu lệnh truy vấn, cần chú ý: Các bảng tham gia kết nối phải được liệt kê sau FROM. Các cột tham gia kết nối phải có miền trị so sánh được với nhau. Tên các cột tham gia kết nối cần được chỉ tường minh theo dạng: <Tên_bảng>.<Tên_cột>
Các cột khác được chỉ tường minh nếu cần thiết.
Điều kiện kết nối được chỉ trong mệnh đề WHERE theo dạng <Tên_bảng_1>.<Tên_cột_1> θ <Tên_bảng_2>.<Tên_cột_2>
trong đó:
+ <Tên_bảng_1>, <Tên_bảng_2>: Các bảng cần kết nối.
+ <Tên_cột_1>, <Tên_cột_2>: Các cột trong các bảng tham gia kết nối.
+ θ : Phép toán kết nối. Thông thường, ta hay sử dụng kết nối tự nhiên nên θ là phép toán “=”.
Ví dụ: Cho xem số hóa đơn, ngày, tên khách hàng trên tất cả các hóa đơn
SELECT SoHD, NgayHD, TenKH FROM KHACHHANG, HOADON
WHERE KHACHHANG.MaKH=HOADON.MaKH) Ví dụ: Đưa ra thông tin các mặt hàng của nhà cung cấp có tên 'Tran Anh' có giá thấp hơn 1000000.
SELECT MATHANG.*
FROM MATHANG, MH_NCC, NHACC
WHERE (MATHANG.MaMH=MH_NCC.MaMH) AND (MH_NCC.MaNCC=NHACC.MaNCC) AND (TenNCC=‘Tran Anh’)AND(DonGia < 1000000)
Ví dụ: Cho biết tên của các nhà cung cấp đã cung cấp từ 5 mặt hàng trở lên.
SELECT TenNCC
FROM NHACC, MH_NCC
WHERE (NHACC.MaNCC= MH_NCC.MaNCC) GROUP BY MaNCC
HAVING Count(Distinct MaMH)>=5 * Sử dụng ánh xạ lồng
Mỗi lệnh khối SELECT thực chất là một ánh xạ. Trong một khối SELECT có thể chứa một khối SELECT khác, khi đó ta có các khối lồng nhau. Ta gọi cấu trúc lồng nhau đó là các ánh xạ lồng. Khi sử dụng ánh xạ lồng, thường sử dụng phép toán IN đẻ kiểm tra một phần tử có thuộc tập hợp không. Các truy vấn dùng ánh xạ lồng thực chất là truy vấn trên từng bảng.
Ví dụ: Cho xem tên của khách hàng trên hóa đơn số 10 SELECT TenKH
FROM KHACHHANG
WHERE MaKH IN SELECT MaKH
FROM HOADON
WHERE SoHD=10
Ví dụ: Cho xem tên của các khách hàng không mua hàng trong ngày 1/6/2008.
SELECT TenKH FROM KHACHHANG
WHERE MaKH NOT IN SELECT MaKH
FROM HOADON WHERE NgayHD=’2008/06/01’
Ví dụ: Cho xem tên các mặt hàng không có người mua trong ngày ’2008/06/01’
SELECT TenMH FROM MATHANG
FROM HD_MH WHERE SoHD IN SELECT SoHD FROM HOADON WHERE NgayHD=’2008/06/01’
c) Các phép toán tập hợp
Để thực hiện phép hợp, giao và trừ trong SQL ta dùng các phép toán: union, intersect và Minus. Cũng như trong đại số quan hệ, việc hợp, giao, trừ các bảng tham gia vào phép toán phải tương thích.
Ví dụ: Cho biết tên các mặt hàng có trong hoá đơn số 5 hoặc số 8 hoặc cả hai. SELECT TenMH FROM MATHANG, HD_MH WHERE (MATHANG.MaMH=HD_MH.MaMH) AND (SoHD=5) union
SELECT TenMH FROM MATHANG, HD_MH WHERE (MATHANG.MaMH=HD_MH.MaMH) AND (SoHD=8)
Ví dụ: Cho biết tên các mặt hàng vừa có trong hoá đon số 5 vừa có trong hoá đơn số 8.
SELECT TenMH FROM MATHANG, HD_MH WHERE (MATHANG.MaMH=HD_MH.MaMH) AND (SoHD=5) Intersect SELECT TenMH FROM MATHANG, HD_MH WHERE (MATHANG.MaMH=HD_MH.MaMH) AND (SoHD=8)
Ví dụ: Cho biết tên các mặt hàng có trong hoá đơn số 5 nhưng không có trong hoá đơn số 8.
SELECT TenMH FROM MATHANG, HD_MH WHERE (MATHANG.MaMH=HD_MH.MaMH) AND (SoHD=5) Minus SELECT TenMH FROM MATHANG, HD_MH WHERE (MATHANG.MaMH=HD_MH.MaMH) AND (SoHD=8) 3.2.4. Giá trị NULL
Trong mỗi dòng của bảng, có thể có một số thuộc tính mà giá trị của chúng là chưa biết, hay không tồn tại. Chẳng hạn để quản lý nhân sự ta cần một bảng HOSO được cho như sau:
Trong đó: MaCB: Mã cán bộ
HoTen: Họ và tên cán bộ
GioiTinh: Giới tính
NgaySinh: Ngày sinh
SoLanSinh: Số lần sinh con
TenVo_Chong: Tên vợ hoặc chồng.
Từ bảng trên ta thấy rằng, thuộc tính SoLanSinh không thể áp dụng cho người có giới tính 'Nam', thuộc tính TenVo_Chong không thể có giá trị nếu cán bộ đó chưa lập gia đình. Vì vậy giá trị
của thuộc tính là không tồn tại hoặc chưa biết. Trong SQL để biểu thị giá trị chưa biết hay không tồn tại người ta dùng hằng NULL.
Để kiểm tra giá trị của thuộc tính có là NULL hay không ta dùng toán tử is. Chẳng hạn, để đưa ra danh sách các cán bộ chưa lập gia đình, ta dùng câu lệnh sau:
SELECT * FROM HOSO
WHERE TenVo_Chong is NULL
3.2.5. Khung nhìn
Như đã nói ở trên, khung nhìn (view) là cách nhìn, quan niệm của người dùng về cơ sở dữ liệu, nó cho phép người viết chương trình định nghĩa lại cơ sở dữ liệu logic theo cách nhìn của họ và tăng khả năng đảm bảo tính độc lập dữ liệu cũng như việc đảm báo tính an toàn và toàn vẹn dữ liệu.
SQL cung cấp một cơ chế cho phép che dấu đi một số dữ liệu đối với người sử dụng bằng việc sử dụng một khung nhìn. Để tạo khung nhìn ta dùng lệnh:
CREATE VIEW <Tên_view>[(<DS_cột>)] AS <Mệnh_đề_SELECT> Trong đó:
- <Tên_view>: Do NSD đặt theo quy định của tên bảng,
- <DS_cột>: Tên các cột của view, có thể khác tên cột trong mệnh đề SELECT.
Ví dụ: Tạo khung nhìn chứa danh sách các mặt hàng đã được cung cấp bởi nhà cung cấp “Sam sung”.
CREATE VIEW HangSS(MaMH, TenMH, DVT, DonGia) AS SELECT MaMH, TenMH, DVTinh, DonGia
WHERE (MATHANG.MaMH= MH_NCC.MaMH) AND (TenNCC='Sum sung');
CÂU HỎI VÀ BÀI TẬP
1. Định nghĩa các phép toán đại số quan hệ. Cho ví dụ. 2. Tính chất của các phép toán đại số quan hệ.
3. Các lệnh của ngôn ngữ đại số quan hệ. 4. Cho 3 quan hệ : r1( A B C ) r2( D E ) r3( B C D) a b b c c b c d d b c c f b c e b b f d f a b d c a d
Thực hiện các phép tính quan hệ sau: a) r1 × r2
b) r1 * r3
c) σD='d' (r1 * r3) d) r1 * r3 * r2
e) ΠBC (r1 * r3 * r2)
5. Cho CSDL gồm các quan hệ sau:
SV(MaSV, TenSV, Diachi, Namsinh, , MaKh) CBGD(MaCB, TenCB, Monday, DThoai, , MaKh) KHOA(MaKh, TenKh, DThoaiKh, TruongKh). a) Tạo các bảng trên bằng ngôn ngữ SQL.
b) Cho xem thông tin về MaSV, TenSV, Namsinh của các sinh viên có địa chỉ là ‘Vinh - Nghe An’.
c) Cho xem thông tin về MaSV, TenSV, Namsinh của các sinh viên có địa chỉ là ‘Vinh - Nghe An’, sinh trước năm 1980.
d) Cho xem thông tin về tên cán bộ, môn dạy, tên khoa của tất cả các cán bộ giảng dạy.
e) Cho xem thông tin về tên cán bộ, môn dạy của các cán bộ giảng dạy khoa “CNTT” (Tênkh=’CNTT’).
f) Cho biết tên các môn có từ 2 cán bộ giảng dạy đảm nhiệm trở lên.
Chương 4.
THIÕT KÕ C¥ Së D÷ LIÖU QUAN HÖ
Khi phát triển một hệ thống thông tin quản lý, câu hỏi đặt ra là ta cần tổ chức bao nhiêu bảng dữ liệu, mỗi bảng gồm các thuộc tính gì và mối quan hệ giữa các bảng như thế nào. Thiết kế cơ sở dữ liệu sẽ giúp ta trả lời các vấn đề đó. Vì vậy, Thiết kế cơ sở dữ liệu là một bộ phận quan trọng trong phát triển hệ thống thông tin quản lý. Việc thiết kế cơ sở dữ liệu sẽ quyết định trực tiếp đến hiệu quả của chương trình, phát triển và bảo trì hệ thống.
4.1. PHỤ THUỘC HÀM 4.1.1. Định nghĩa 4.1.1. Định nghĩa
Đặt vấn đề
Phụ thuộc hàm là khái niệm được xây dựng để mô tả các ràng buộc dữ liệu trong cơ sở dữ liệu. Chẳng hạn trong quan hệ HOADON(SoHD, Ngay, TenKH) sau:
SoHD Ngay TenKH
1 2 3 4 5 1-1-2010 20-2-2010 10-5-2010 1-6-2010 2-6-2010 Nguyen An Le Anh Tran Trung Nguyen An Tran Kiem
Để thể hiện ràng buộc "Mỗi số hóa đơn chỉ có một khách hàng" ta viết: SoHD→ TenKH, và nói rằng thuộc tính SoHD xác định thuộc
tính TenKH. Hay thuộc tính TenKH phụ thuộc hàm vào thuộc tính SoHD. Với ràng buộc đó hệ cơ sở dữ liệu này sẽ từ chối không nạp bộ <3, 12-5-2010, ‘Nguyen An’> vào quan hệ HOADON vì nếu không, sẽ có hai tên khách hàng trên hóa đơn số 3.
Định nghĩa phụ thuộc hàm
Cho lược đồ quan hệ R(U) với U = {A1, . . . , An} và các tập