Apache Derby Bài 12: Truy vấn nâng cao: Sắp xếp, nhóm dữ liệu (ORDER BY, GROUP BY, HAVING)
1. Mở rộng khả năng của lệnh SELECT
Trong thực tế, việc chỉ trích xuất các dòng dữ liệu rời rạc bằng SELECT và WHERE là chưa đủ để phục vụ cho các hệ thống báo cáo (Reporting) hoặc bảng điều khiển (Dashboard). Chúng ta cần sắp xếp dữ liệu theo thứ tự ưu tiên, hoặc gom nhóm các bản ghi lại để tính toán tổng số, trung bình, lớn nhất và nhỏ nhất.
Bộ ba mệnh đề ORDER BY, GROUP BY và HAVING trong SQL chính là công cụ cốt lõi để giải quyết bài toán thống kê và tổ chức dữ liệu này.
2. Sắp xếp kết quả với ORDER BY
Mệnh đề ORDER BY luôn được đặt ở cuối cùng trong một câu lệnh truy vấn. Nó có nhiệm vụ sắp xếp tập kết quả trả về theo một hoặc nhiều cột.
-
ASC (Ascending): Sắp xếp tăng dần (từ A-Z, từ nhỏ đến lớn, từ cũ đến mới). Đây là hành vi mặc định nếu bạn không ghi gì.
-
DESC (Descending): Sắp xếp giảm dần (từ Z-A, từ lớn đến nhỏ, từ mới đến cũ).
Sắp xếp theo một cột
Truy vấn danh sách sản phẩm và hiển thị những mặt hàng có giá bán cao nhất lên đầu:
SQL
SELECT ma_san_pham, ten_san_pham, gia_niem_yet
FROM san_pham
ORDER BY gia_niem_yet DESC;
Sắp xếp theo nhiều cột (Multi-column Sort)
Khi có nhiều bản ghi trùng giá trị ở cột sắp xếp đầu tiên, Derby sẽ tiếp tục sử dụng cột thứ hai để phân định.
SQL
-- Sắp xếp theo danh mục (A-Z), nếu trùng danh mục thì xếp theo giá giảm dần
SELECT ten_san_pham, ma_danh_muc, gia_niem_yet
FROM san_pham
ORDER BY ma_danh_muc ASC, gia_niem_yet DESC;
3. Các hàm tổng hợp (Aggregate Functions)
Trước khi gom nhóm, bạn cần nắm vững các hàm tổng hợp toán học tích hợp sẵn trong Derby. Các hàm này nhận đầu vào là một tập hợp các giá trị và trả về một kết quả duy nhất:
-
COUNT(cot)hoặcCOUNT(*): Đếm số lượng bản ghi. -
SUM(cot): Tính tổng các giá trị trong cột (chỉ áp dụng cho số). -
AVG(cot): Tính trung bình cộng (chỉ áp dụng cho số). -
MAX(cot)/MIN(cot): Tìm giá trị lớn nhất / nhỏ nhất.
4. Phân nhóm dữ liệu với GROUP BY
Mệnh đề GROUP BY gộp các dòng có cùng giá trị ở một (hoặc nhiều) cột thành các dòng tóm tắt. Nó bắt buộc phải đi kèm với các hàm tổng hợp ở mệnh đề SELECT.
Quy tắc vàng của GROUP BY: Bất kỳ cột nào xuất hiện trong mệnh đề SELECT mà không nằm trong một hàm tổng hợp, thì bắt buộc phải có mặt trong mệnh đề GROUP BY.
Ví dụ: Thống kê theo danh mục
Tính tổng số lượng mặt hàng và giá trung bình của từng danh mục sản phẩm:
SQL
SELECT
ma_danh_muc,
COUNT(*) AS tong_so_mat_hang,
AVG(gia_niem_yet) AS muc_gia_trung_binh
FROM san_pham
GROUP BY ma_danh_muc;
Kết quả trả về sẽ gộp toàn bộ sản phẩm của DM_DIEN_TU thành 1 dòng duy nhất, gộp DM_GIA_DUNG thành 1 dòng duy nhất và thực hiện phép toán trên các nhóm đó.
5. Lọc các nhóm với HAVING
Nhiều người mới học SQL thường nhầm lẫn giữa WHERE và HAVING. Điểm khác biệt mấu chốt là:
-
WHERE: Lọc các dòng dữ liệu đơn lẻ TRƯỚC KHI quá trình gom nhómGROUP BYdiễn ra. -
HAVING: Lọc các kết quả tổng hợp SAU KHI đã gom nhóm xong. Không thể dùng hàm tổng hợp (nhưSUM,COUNT) bên trongWHERE.
Ví dụ: Tìm các danh mục có lượng tồn kho lớn
Bạn muốn tìm ra những danh mục sản phẩm đang có tổng số lượng tồn kho trên toàn hệ thống lớn hơn 500:
SQL
SELECT
ma_danh_muc,
SUM(so_luong_kho) AS tong_ton_kho
FROM san_pham
GROUP BY ma_danh_muc
HAVING SUM(so_luong_kho) > 500;
(Nếu bạn dùng WHERE SUM(so_luong_kho) > 500 ở đây, Derby sẽ lập tức báo lỗi cú pháp).
6. Trình tự thực thi logic của một truy vấn SQL
Để không bao giờ viết sai cú pháp khi kết hợp toàn bộ các mệnh đề, bạn cần hiểu Engine của Derby (và mọi RDBMS chuẩn) thực thi câu lệnh theo thứ tự nào phía sau hậu trường:
-
FROM: Xác định bảng nguồn cần lấy dữ liệu. -
WHERE: Loại bỏ các dòng không thỏa mãn điều kiện logic. -
GROUP BY: Gộp các dòng còn lại thành từng nhóm. -
HAVING: Loại bỏ các nhóm không đạt yêu cầu. -
SELECT: Trích xuất các cột và tính toán kết quả của hàm tổng hợp (SUM, AVG...). -
ORDER BY: Sắp xếp thứ tự của bảng kết quả cuối cùng trước khi trả về cho Client.
7. Tổng kết
-
ORDER BYgiúp điều hướng hiển thị dữ liệu theo chiều tăng (ASC) hoặc giảm (DESC). -
GROUP BYlà công cụ để viết các câu lệnh báo cáo, đi kèm với các hàm tính toánSUM,COUNT,AVG,MAX,MIN. -
HAVINGlà bộ lọc chuyên dụng dành riêng cho các kết quả sinh ra từ hàm tổng hợp, bù đắp cho sự thiếu hụt củaWHERE.
Bài tiếp theo sẽ đưa chúng ta đến một trong những kỹ thuật mạnh mẽ nhất của cơ sở dữ liệu quan hệ – cách lấy dữ liệu từ nhiều bảng cùng lúc: Apache Derby Bài 13: Các kỹ thuật nối bảng (Inner Join, Left/Right Outer Join) trong Derby SQL.
All rights reserved