Ngoài khả năng thực hiện cỏc yờu cầu truy vấn dữ liệu thụng thường (chiếu, chọn, nối,…) như đó đề cập như ở cỏc phần trước, cõu lệnh SELECT cũn cho phộp thực hiện cỏc thao tỏc truy vấn và tớnh toỏn thống kờ trờn dữ liệu như: cho biết tổng số tiết dạy của mỗi giỏo viờn, điểm trung bỡnh cỏc mụn học của mỗi sinh viờn,…
Mệnh đề GROUP BY sử dụng trong cõu lệnh SELECT nhằm phõn hoạch cỏc dũng dữ liệu trong bảng thành cỏc nhúm dữ liệu, và trờn mỗi nhúm dữ liệu thực hiện tớnh toỏn cỏc giỏ trị thống kờ như tớnh tổng, tớnh giỏ trị trung bỡnh,...
Cỏc hàm gộp được sử dụng để tớnh giỏ trị thống kờ cho toàn bảng hoặc trờn mỗi nhúm dữ liệu. Chỳng cú thể được sử dụng như là cỏc cột trong danh sỏch chọn của cõu lệnh SELECT hoặc xuất hiện trong mệnh đề HAVING, nhưng khụng được phộp xuất hiện trong mệnh đề WHERE
SQL cung cấp cỏc hàm gộp dưới đõy:
Hàm gộp Chức năng
SUM([ALL | DISTINCT] biểu_thức) Tớnh tổng cỏc giỏ trị.
AVG([ALL | DISTINCT] biểu_thức) Tớnh trung bỡnh của cỏc giỏ trị COUNT([ALL | DISTINCT] biểu_thức) Đếm số cỏc giỏ trị trong biểu thức.
COUNT(*) Đếm số cỏc dũng được chọn.
MAX(biểu_thức) Tớnh giỏ trị lớn nhất MIN(biểu_thức) Tớnh giỏ trị nhỏ nhất Trong đú:
• Hàm SUM và AVG chỉ làm việc với cỏc biểu thức số.
• Hàm SUM, AVG, COUNT, MIN và MAX bỏ qua cỏc giỏ trị NULL khi tớnh toỏn.
• Hàm COUNT(*) khụng bỏ qua cỏc giỏ trị NULL.
Mặc định, cỏc hàm gộp thực hiện tớnh toỏn thống kờ trờn toàn bộ dữ liệu. Trong trường hợp cần loại bỏ bớt cỏc giỏ trị trựng nhau (chỉ giữ lại một giỏ trị), ta chỉ định thờm từ khoỏ DISTINCT ở trước biểu thức là đối số của hàm.
Khi cần tớnh toỏn giỏ trị thống kờ trờn toàn bộ dữ liệu, ta sử dụng cỏc hàm gộp trong danh sỏch chọn của cõu lệnh SELECT. Trong trường hợp này, trong danh sỏch chọn khụng được sử dụng bất kỳ một tờn cột hay biểu thức nào ngoài cỏc hàm gộp.
Vớ dụ 2.35: Để thống kờ trung bỡnh điểm lần 1 của tất cả cỏc mụn học, ta sử dụng cõu lệnh như sau:
SELECT AVG(diemlan1) FROM diemthi
cũn cõu lệnh dưới đõy cho biết tuổi lớn nhất, tuổi nhỏ nhất và độ tuổi trung bỡnh của tất cả cỏc sinh viờn sinh tại Huế:
SELECT MAX(YEAR(GETDATE())-YEAR(ngaysinh)), MIN(YEAR(GETDATE())-YEAR(ngaysinh)), AVG(YEAR(GETDATE())-YEAR(ngaysinh)) FROM sinhvien WHERE noisinh=’Huế’ Thống kờ dữ liệu trờn cỏc nhúm
Trong trường hợp cần thực hiện tớnh toỏn cỏc giỏ trị thống kờ trờn cỏc nhúm dữ liệu, ta sử dụng mệnh đề GROUP BY để phõn hoạch dữ liệu vào trong cỏc nhúm. Cỏc hàm gộp được sử dụng sẽ thực hiện thao tỏc tớnh toỏn trờn mỗi nhúm và cho biết giỏ trị thống kờ theo cỏc nhúm dữ liệu.
Vớ dụ 2.36: Cõu lệnh dưới đõy cho biết sĩ số (số lượng sinh viờn) của mỗi lớp
SELECT lop.malop,tenlop,COUNT(masv) AS siso FROM lop,sinhvien WHERE lop.malop=sinhvien.malop GROUP BY lop.malop,tenlop và cú kết quả là cũn cõu lệnh: SELECT sinhvien.masv,hodem,ten,
sum(diemlan1*sodvht)/sum(sodvht) FROM sinhvien,diemthi,monhoc
WHERE sinhvien.masv=diemthi.masv AND diemthi.mamonhoc=monhoc.mamonhoc
GROUP BY sinhvien.masv,hodem,ten
cho biết trung bỡnh điểm thi lần 1 cỏc mụn học của cỏc sinh viờn
Lưu ý: Trong trường hợp danh sỏch chọn của cõu lệnh SELECT cú cả cỏc hàm gộp và những biểu thức khụng phải là hàm gộp thỡ những biểu thức này phải cú mặt đầy đủ trong mệnh đề GROUP BY, nếu khụng cõu lệnh sẽ khụng hợp lệ.
Vớ dụ 2.37: Dưới đõy là một cõu lệnh sai
SELECT lop.malop,tenlop,COUNT(masv) FROM lop,sinhvien
WHERE lop.malop=sinhvien.malop GROUP BY lop.malop
do thiếu trường TENLOP sau mệnh đề GROUP BY.
Chỉ định điều kiện đối với hàm gộp
Mệnh đề HAVING được sử dụng nhằm chỉ định điều kiện đối với cỏc giỏ trị thống kờ được sản sinh từ cỏc hàm gộp tương tự như cỏch thức mệnh đề WHERE thiết lập cỏc điều kiện cho cõu lệnh SELECT. Mệnh đề HAVING thường khụng thực sự cú nghĩa nếu như khụng sử dụng kết hợp với mệnh đề GROUP BY. Một điểm khỏc biệt giữa HAVING và WHERE là trong điều kiện của WHERE khụng được cú cỏc hàm gộp trong khi HAVING lại cho phộp sử dụng cỏc hàm gộp trong điều kiện của mỡnh.
Vớ dụ 2.38: Để biết trung bỡnh điểm thi lần 1 của cỏc sinh viờn cú điểm trung bỡnh lớn hơn hoặc bằng 5, ta sử dụng cõu lệnh như sau:
SELECT sinhvien.masv,hodem,ten,
SUM(diemlan1*sodvht)/sum(sodvht) FROM sinhvien,diemthi,monhoc
WHERE sinhvien.masv=diemthi.masv AND diemthi.mamonhoc=monhoc.mamonhoc
GROUP BY sinhvien.masv,hodem,ten
HAVING sum(diemlan1*sodvht)/sum(sodvht)>=5