Apache Derby Bài 13: Các kỹ thuật nối bảng (Inner Join, Left/Right Outer Join) trong Derby SQL
1. Sự cần thiết của thao tác nối bảng (JOIN)
Trong cơ sở dữ liệu quan hệ (RDBMS), quá trình chuẩn hóa (Normalization) yêu cầu chúng ta chia nhỏ dữ liệu thành nhiều bảng khác nhau để tránh dư thừa và dễ dàng cập nhật. Ví dụ: thông tin danh mục nằm ở bảng danh_muc, còn thông tin sản phẩm nằm ở bảng thiet_bi.
Tuy nhiên, khi làm báo cáo hoặc hiển thị lên giao diện người dùng, bạn lại cần xem tên sản phẩm đi kèm với tên danh mục thực tế thay vì những mã ID vô nghĩa. Đây là lúc mệnh đề JOIN phát huy tác dụng. Lệnh JOIN sẽ dựa vào mối quan hệ giữa các cột (thường là Khóa chính - Khóa ngoại) để "lắp ráp" dữ liệu từ nhiều bảng lại thành một bảng kết quả duy nhất.
2. Kỹ thuật bí danh (Table Aliases)
Trước khi viết các câu lệnh JOIN, bạn cần làm quen với kỹ thuật đặt bí danh cho bảng. Khi truy vấn từ nhiều bảng, các bảng thường có những cột trùng tên (ví dụ cột ma_danh_muc vừa có ở bảng cha, vừa có ở bảng con).
Để trình biên dịch Derby biết bạn đang ám chỉ cột của bảng nào, bạn phải thêm tiền tố ten_bang.ten_cot. Bí danh (AS) giúp rút gọn tiền tố này:
SQL
SELECT d.ten_danh_muc, t.ten_thiet_bi
FROM danh_muc AS d, thiet_bi AS t;
-- (Từ khóa AS có thể bỏ qua: FROM danh_muc d, thiet_bi t)
3. INNER JOIN (Nối bằng / Nối trong)
INNER JOIN là loại nối phổ biến nhất. Nó hoạt động như phép giao của hai tập hợp: kết quả chỉ trả về những bản ghi có sự trùng khớp giá trị khóa ở cả hai bảng.
Cú pháp:
SQL
SELECT cot1, cot2
FROM bang_A
INNER JOIN bang_B ON bang_A.khoa_chinh = bang_B.khoa_ngoai;
Ví dụ thực tế:
Lấy danh sách tất cả các thiết bị kèm theo tên danh mục của chúng. Nếu một thiết bị chưa được gán danh mục, hoặc một danh mục chưa có thiết bị nào, chúng sẽ không xuất hiện trong kết quả.
SQL
SELECT
t.ma_thiet_bi,
t.ten_thiet_bi,
d.ten_danh_muc,
t.gia_tien
FROM thiet_bi t
INNER JOIN danh_muc d ON t.ma_danh_muc = d.ma_danh_muc;
4. LEFT OUTER JOIN (Nối trái)
LEFT JOIN (hoặc LEFT OUTER JOIN) ưu tiên bảng nằm bên trái chữ JOIN. Hệ thống sẽ lấy toàn bộ các bản ghi từ bảng bên trái, bất kể chúng có bản ghi tương ứng ở bảng bên phải hay không. Nếu không có sự trùng khớp, các cột của bảng bên phải sẽ được lấp đầy bởi giá trị NULL.
Ví dụ thực tế:
Bạn muốn liệt kê tất cả các danh mục sản phẩm đang có trong hệ thống, kèm theo tên thiết bị thuộc danh mục đó (nếu có). Những danh mục mới tạo, chưa có bất kỳ thiết bị nào, vẫn phải được hiển thị lên màn hình.
SQL
SELECT
d.ma_danh_muc,
d.ten_danh_muc,
t.ten_thiet_bi
FROM danh_muc d
LEFT JOIN thiet_bi t ON d.ma_danh_muc = t.ma_danh_muc;
Kết quả: Các danh mục như DM_MAY_TINH dù chưa có sản phẩm nào bên trong vẫn sẽ hiện ra, nhưng giá trị ở cột ten_thiet_bi sẽ là NULL.
5. RIGHT OUTER JOIN (Nối phải)
RIGHT JOIN hoạt động giống hệt LEFT JOIN, chỉ khác ở điểm nó ưu tiên bảng nằm bên phải chữ JOIN. Toàn bộ dữ liệu bảng bên phải sẽ được giữ lại, và nếu bảng bên trái không có dòng nào khớp, giá trị NULL sẽ được thay thế.
SQL
SELECT
d.ten_danh_muc,
t.ten_thiet_bi
FROM danh_muc d
RIGHT JOIN thiet_bi t ON d.ma_danh_muc = t.ma_danh_muc;
Mẹo thực tế: Hầu hết lập trình viên thường chỉ dùng
LEFT JOINvà sắp xếp lại thứ tự bảng trong câu lệnh thay vì dùngRIGHT JOINđể dễ đọc luồng tư duy từ trên xuống dưới (từ bảng gốc trỏ ra bảng phụ).
6. Kết hợp JOIN với các mệnh đề khác
Sức mạnh thực sự của SQL là khả năng kết nối nhiều khối logic lại với nhau. Bạn hoàn toàn có thể nối nhiều bảng, sau đó áp dụng bộ lọc WHERE, gom nhóm GROUP BY và sắp xếp ORDER BY.
Ví dụ nâng cao: Viết báo cáo đếm số lượng thiết bị đang có trong từng danh mục, hiển thị cả những danh mục chưa có thiết bị nào (tức là số lượng = 0), và sắp xếp từ cao xuống thấp.
SQL
SELECT
d.ten_danh_muc,
COUNT(t.ma_thiet_bi) AS so_luong_thiet_bi
FROM danh_muc d
LEFT JOIN thiet_bi t ON d.ma_danh_muc = t.ma_danh_muc
GROUP BY d.ten_danh_muc
ORDER BY so_luong_thiet_bi DESC;
(Lưu ý: Dùng COUNT(t.ma_thiet_bi) thay vì COUNT(*) để các dòng có giá trị NULL ở phía thiet_bi sẽ được đếm là 0).
7. Tổng kết phần SQL cơ sở
-
INNER JOIN: Dùng khi chỉ muốn lấy dữ liệu hợp lệ hoàn toàn ở cả 2 bảng. -
LEFT JOIN: Dùng khi muốn lấy toàn bộ danh sách gốc (bảng trái) và bổ sung thêm thông tin phụ (bảng phải) nếu có. -
Việc nắm vững các loại JOIN là kỹ năng bắt buộc để truy vấn các cơ sở dữ liệu đã được chuẩn hóa.
Tới đây, chúng ta đã hoàn tất phần nền tảng thao tác cơ sở dữ liệu với công cụ ij. Phần tiếp theo sẽ đưa chúng ta vào thế giới thực của Java, nơi mã nguồn kết nối trực tiếp với database: Apache Derby Bài 14: Thiết lập dự án Maven/Gradle với thư viện derby.jar.
All rights reserved