Bài 23: Thực hành truy xuất dữ liệu qua liên kết các bảng

Hình 23.4 – Mô tả giao diện Quản lí danh sách các bản thu âm (Ảnh Sách KNTT)

I. Lý thuyết trọng tâm

Các bảng trong cơ sở dữ liệu có thể có quan hệ với nhau thông qua khoá ngoài. Nhờ mối quan hệ này, ta có thể truy xuất dữ liệu từ nhiều bảng cùng lúc bằng câu truy vấn SQL sử dụng mệnh đề JOIN. Đây là kỹ thuật quan trọng giúp kết hợp thông tin nằm rải rác ở các bảng khác nhau thành một kết quả truy vấn thống nhất.

II. Hướng dẫn thực hành

Nhiệm vụ 1: Lập danh sách các bản nhạc với tên bản nhạc và tên tác giả

a) Truy vấn liên kết hai bảng qua khoá ngoài

Bảng bannhac có cấu trúc: bannhac(idBannhac, tenBannhac, idNhacsi, idTheloai). Trong các trường này không có trường tenNhacsi. Vậy làm thế nào để lập danh sách các bản nhạc kèm tên nhạc sĩ sáng tác?

Tên nhạc sĩ nằm trong bảng nhacsi(idNhacsi, tenNhacsi). Bảng bannhac có khoá ngoài idNhacsi tham chiếu đến khoá chính idNhacsi của bảng nhacsi. Nhờ mối liên kết này, ta có thể truy vấn dữ liệu từ cả hai bảng đồng thời.

Cấu trúc câu truy vấn SQL liên kết hai bảng bằng mệnh đề INNER JOIN:

SELECT  danh_sách_tên_trường_của_2_bảng
FROM    tên_bảng_a INNER JOIN tên_bảng_b
  ON    tên_bảng_a.tên_trường_a = tên_bảng_b.tên_trường_b
  [WHERE  ...]
  [ORDER BY  ...]  ;

Trong đó, mệnh đề ON chỉ rõ điều kiện liên kết: trường khoá ngoài ở bảng này bằng trường khoá chính ở bảng kia.

Ví dụ: Lấy ra danh sách các bản nhạc gồm tenBannhac và tenNhacsi:

SELECT  bannhac.tenBannhac, nhacsi.tenNhacsi
FROM    bannhac INNER JOIN nhacsi
  ON    bannhac.idNhacsi = nhacsi.idNhacsi;

Thao tác thực hiện: Vào HeidiSQL, chọn CSDL mymusic, chọn thẻ Truy vấn và nhập câu truy vấn ở trên. Nhấn F9 trên bàn phím hoặc nháy chuột vào biểu tượng ▶ hoặc nháy nút phải chuột chọn Chạy.

Nếu muốn lấy tất cả các trường của bảng bannhac kèm tenNhacsi, có thể dùng dấu * thay cho danh sách tên trường:

SELECT  bannhac.*, nhacsi.tenNhacsi
FROM    bannhac INNER JOIN nhacsi
  ON    bannhac.idNhacsi = nhacsi.idNhacsi;
Hình 23.1 – Kết quả truy vấn liên kết hai bảng theo trường khoá (Ảnh Sách KNTT)
Hình 23.1 – Kết quả truy vấn liên kết hai bảng theo trường khoá (Ảnh Sách KNTT)

b) Đối chiếu khoá ngoài bằng bí danh (AS)

Khi kết quả truy xuất có cả trường idNhacsi từ bảng bannhac và idNhacsi từ bảng nhacsi, hai trường này cùng tên nên có thể gây nhầm lẫn. Để đối chiếu một cách tường minh, ta có thể đổi tên hiển thị bằng từ khoá AS (bí danh):

SELECT  bannhac.tenBannhac,
        bannhac.idNhacsi AS idNS_BN,
        nhacsi.idNhacsi AS idNS_NS,
        nhacsi.tenNhacsi
FROM    bannhac INNER JOIN nhacsi
  ON    bannhac.idNhacsi = nhacsi.idNhacsi;

Ở đây, idNS_BN là bí danh cho idNhacsi lấy từ bảng bannhac, còn idNS_NS là bí danh cho idNhacsi lấy từ bảng nhacsi. Kết quả cho thấy hai cột này luôn có giá trị giống nhau – xác nhận liên kết đúng.

Hình 23.2 – Kết quả truy vấn liên kết hai bảng với khoá đối chiếu (Ảnh Sách KNTT)
Hình 23.2 – Kết quả truy vấn liên kết hai bảng với khoá đối chiếu (Ảnh Sách KNTT)

c) Hỗ trợ của HeidiSQL khi nhập truy vấn

HeidiSQL hỗ trợ người dùng khi nhập các câu truy vấn theo các phương thức sau:

  • Tô màu cú pháp (syntax coloring): Dùng màu sắc để trợ giúp quan sát cú pháp của câu truy vấn, giúp dễ dàng nhận biết từ khoá, tên bảng, tên trường.
  • Tự động gợi ý: Mỗi khi người dùng nhập một tên bảng và dấu chấm (.), HeidiSQL sẽ hiển thị ngay danh sách các tên trường của bảng đó để người dùng lựa chọn, giúp tránh nhập sai tên trường.
Hình 23.3 – Một giao diện hỗ trợ người dùng của HeidiSQL
Hình 23.3 – Một giao diện hỗ trợ người dùng của HeidiSQL

d) Thực hành thêm

  • Lập danh sách bao gồm idBannhac, tenBannhac, tenNhacsi từ tất cả các bản nhạc có trong bảng bannhac.
  • Lập danh sách bao gồm idBannhac, tenBannhac từ tất cả các bản nhạc của nhạc sĩ Đỗ Nhuận có trong bảng bannhac.

Ví dụ câu truy vấn cho yêu cầu thứ hai:

SELECT  bannhac.idBannhac, bannhac.tenBannhac
FROM    bannhac INNER JOIN nhacsi
  ON    bannhac.idNhacsi = nhacsi.idNhacsi
WHERE   nhacsi.tenNhacsi = 'Đỗ Nhuận';

Nhiệm vụ 2: Lập danh sách các bản thu âm với đủ các thông tin idBanthuam, tenBannhac, tenCasi

Khi cần truy vấn dữ liệu từ nhiều hơn hai bảng theo liên kết khoá ngoài, ta lặp lại mệnh đề INNER JOIN trong câu truy vấn SQL theo cấu trúc:

SELECT  danh_sách_tên_trường_của_3_bảng
FROM    tên_bảng_a
  INNER JOIN tên_bảng_b
    ON  tên_bảng_a.tên_trường_a = tên_bảng_b.tên_trường_b
  INNER JOIN tên_bảng_c
    ON  tên_bảng_x.tên_trường_x = tên_bảng_c.tên_trường_c
  [WHERE  ...]
  [ORDER BY  ...]  ;

Trong đó tên_bảng_x.tên_trường_x là tên trường của bảng a hay bảng b (bảng đã xuất hiện trước đó trong câu truy vấn).

Ví dụ: Lấy danh sách bản thu âm gồm idBanthuam, tenBannhac, tenCasi. Bảng banthuam có khoá ngoài idBannhac (tham chiếu bảng bannhac) và idCasi (tham chiếu bảng casi). Do đó cần liên kết 3 bảng:

SELECT  banthuam.idBanthuam,
        bannhac.tenBannhac,
        casi.tenCasi
FROM    banthuam
  INNER JOIN bannhac
    ON  banthuam.idBannhac = bannhac.idBannhac
  INNER JOIN casi
    ON  banthuam.idCasi = casi.idCasi;

Nhiệm vụ 3: Tìm hiểu một chức năng của ứng dụng Quản lí dữ liệu âm nhạc

Hình 23.4 – Mô tả giao diện Quản lí danh sách các bản thu âm (Ảnh Sách KNTT)
Hình 23.4 – Mô tả giao diện Quản lí danh sách các bản thu âm (Ảnh Sách KNTT)

Qua giao diện trong Hình 23.4, em hãy tìm hiểu một chức năng của ứng dụng Quản lí dữ liệu âm nhạc, so sánh với những kiến thức vừa được học trong bài thực hành và cho nhận xét so sánh. Cách tương tác với giao diện này tương tự với giao diện Quản lí danh sách các bản nhạc ở Bài 22 (Hình 22.7), chỉ khác ở chỗ khi nhập bản thu âm, người dùng chọn tên bản nhạc và tên ca sĩ từ hộp danh sách với những tên đã có trong CSDL. Danh sách các bản thu âm hiển thị đầy đủ các thông tin tường minh: tên bản nhạc, tên nhạc sĩ và tên ca sĩ thể hiện.

Nhận xét so sánh:

  • Người sử dụng không cần biết, nhớ cấu trúc của các bảng trong CSDL.
  • Giao diện dễ hiểu, dễ sử dụng, hướng vào nghiệp vụ hàng ngày.
  • Hình thức nhập dữ liệu thông qua hộp danh sách giúp hỗ trợ tính nhất quán dữ liệu, vì người dùng chỉ chọn từ những giá trị đã có sẵn thay vì nhập tay.

III. Hướng dẫn giải bài tập SGK

Bài Luyện tập

Đề bài: Lấy danh sách các bản thu âm với đầy đủ các thông tin: idBanthuam, tenBannhac, tenNhacsi, tenCasi.

Hướng dẫn:

Yêu cầu này cần kết hợp dữ liệu từ 4 bảng: banthuam, bannhac, nhacsi, casi. Chuỗi liên kết:

  • banthuam.idBannhac → bannhac.idBannhac (lấy tenBannhac)
  • bannhac.idNhacsi → nhacsi.idNhacsi (lấy tenNhacsi)
  • banthuam.idCasi → casi.idCasi (lấy tenCasi)

Câu truy vấn SQL:

SELECT  banthuam.idBanthuam,
        bannhac.tenBannhac,
        nhacsi.tenNhacsi,
        casi.tenCasi
FROM    banthuam
  INNER JOIN bannhac
    ON  banthuam.idBannhac = bannhac.idBannhac
  INNER JOIN nhacsi
    ON  bannhac.idNhacsi = nhacsi.idNhacsi
  INNER JOIN casi
    ON  banthuam.idCasi = casi.idCasi;

Chọn thẻ Truy vấn trong HeidiSQL, nhập câu lệnh trên và nhấn F9 để chạy. Kết quả hiển thị danh sách đầy đủ: mã bản thu âm, tên bản nhạc, tên nhạc sĩ sáng tác, tên ca sĩ thể hiện.

Bài Vận dụng

Bài 1. Lấy danh sách các bản thu âm với các thông tin: idBanthuam, tenBannhac, tenCasi – các bản nhạc của nhạc sĩ Văn Cao.

Hướng dẫn:

SELECT  banthuam.idBanthuam,
        bannhac.tenBannhac,
        casi.tenCasi
FROM    banthuam
  INNER JOIN bannhac
    ON  banthuam.idBannhac = bannhac.idBannhac
  INNER JOIN nhacsi
    ON  bannhac.idNhacsi = nhacsi.idNhacsi
  INNER JOIN casi
    ON  banthuam.idCasi = casi.idCasi
WHERE   nhacsi.tenNhacsi = 'Văn Cao';

Bài 2. Lấy danh sách các bản thu âm với các thông tin: idBanthuam, tenBannhac, tenTacgia – các bản nhạc do ca sĩ Lê Dung thể hiện.

Hướng dẫn:

Ở đây tenTacgia chính là tenNhacsi, ta dùng bí danh AS để đổi tên hiển thị:

SELECT  banthuam.idBanthuam,
        bannhac.tenBannhac,
        nhacsi.tenNhacsi AS tenTacgia
FROM    banthuam
  INNER JOIN bannhac
    ON  banthuam.idBannhac = bannhac.idBannhac
  INNER JOIN nhacsi
    ON  bannhac.idNhacsi = nhacsi.idNhacsi
  INNER JOIN casi
    ON  banthuam.idCasi = casi.idCasi
WHERE   casi.tenCasi = 'Lê Dung';

Bài 3. Lấy danh sách các bản thu âm với các thông tin: idBanthuam, tenBannhac, tenTacgia, tenCasi – các bản nhạc do ca sĩ Lê Dung thể hiện thuộc thể loại Nhạc trữ tình.

Hướng dẫn:

Bài này yêu cầu thêm điều kiện lọc theo thể loại, cần liên kết thêm bảng theloai (nếu CSDL đã mở rộng thêm bảng này với trường idTheloai trong bảng bannhac):

SELECT  banthuam.idBanthuam,
        bannhac.tenBannhac,
        nhacsi.tenNhacsi AS tenTacgia,
        casi.tenCasi
FROM    banthuam
  INNER JOIN bannhac
    ON  banthuam.idBannhac = bannhac.idBannhac
  INNER JOIN nhacsi
    ON  bannhac.idNhacsi = nhacsi.idNhacsi
  INNER JOIN casi
    ON  banthuam.idCasi = casi.idCasi
  INNER JOIN theloai
    ON  bannhac.idTheloai = theloai.idTheloai
WHERE   casi.tenCasi = 'Lê Dung'
  AND   theloai.tenTheloai = 'Nhạc trữ tình';

Bài 4. Thực hành truy xuất bảng Phường/Xã qua liên kết với bảng Tỉnh/Thành phố

Hướng dẫn:

Dựa trên CSDL quản lí danh sách tên phường/xã, tỉnh/thành phố đã tạo ở các bài trước, với bảng phuongxa(idPhuongxa, tenPhuongxa, idTinhtp) và bảng tinhtp(idTinhtp, tenTinhtp). Để lấy danh sách phường/xã kèm theo tên tỉnh/thành phố, sử dụng câu lệnh:

SELECT  phuongxa.idPhuongxa,
        phuongxa.tenPhuongxa,
        tinhtp.tenTinhtp
FROM    phuongxa INNER JOIN tinhtp
  ON    phuongxa.idTinhtp = tinhtp.idTinhtp
ORDER BY tinhtp.tenTinhtp, phuongxa.tenPhuongxa;

Câu lệnh trên sử dụng phép INNER JOIN để liên kết hai bảng thông qua trường idTinhtp, từ đó hiển thị tên phường/xã cùng với tên tỉnh/thành phố tương ứng.

Nếu muốn lọc các phường/xã thuộc một tỉnh/thành phố cụ thể, thêm mệnh đề WHERE. Ví dụ, lấy danh sách các phường/xã thuộc Hà Nội:

SELECT  phuongxa.idPhuongxa,
        phuongxa.tenPhuongxa,
        tinhtp.tenTinhtp
FROM    phuongxa INNER JOIN tinhtp
  ON    phuongxa.idTinhtp = tinhtp.idTinhtp
WHERE   tinhtp.tenTinhtp = 'Hà Nội'
ORDER BY phuongxa.tenPhuongxa;

Chọn nút Chạy (▶) để thực hiện truy vấn và xem kết quả. Các phường/xã sẽ được hiển thị kèm theo tên tỉnh/thành phố tương ứng hoặc chỉ các phường/xã thuộc tỉnh/thành phố được chỉ định trong mệnh đề WHERE.

Thầy Phạm Thành Danh

Thầy Phạm Thành Danh

(Người kiểm duyệt, ra đề)

Chức vụ: Trưởng ban biên soạn môn Tin Học THPT

Trình độ: Cử nhân Sư phạm Tin học, Chứng chỉ hạng II, Chứng chỉ Tin học, Ngoại ngữ B1

Kinh nghiệm: 8+ năm kinh nghiệm tại Trường THPT Thuận Hóa