### Mối quan hệ nhiều nhiều : `Books`, `Authors`,`BookAuthors` ### 1. Tạo Bảng (CREATE TABLE) Đầu tiên, chúng ta sẽ tạo ba bảng: `Authors`, `Books`, và `BookAuthors`. ```sql -- Bảng Authors CREATE TABLE Authors ( AuthorID INT PRIMARY KEY IDENTITY(1,1), FirstName NVARCHAR(50) NOT NULL, LastName NVARCHAR(50) NOT NULL, BirthDate DATE, Country NVARCHAR(50) ); -- Bảng Books CREATE TABLE Books ( BookID INT PRIMARY KEY IDENTITY(1,1), Title NVARCHAR(255) NOT NULL, PublicationYear INT, Genre NVARCHAR(50) ); -- Bảng trung gian BookAuthors để tạo mối quan hệ nhiều-nhiều CREATE TABLE BookAuthors ( BookID INT NOT NULL, AuthorID INT NOT NULL, PRIMARY KEY (BookID, AuthorID), -- Khóa chính kép FOREIGN KEY (BookID) REFERENCES Books(BookID), FOREIGN KEY (AuthorID) REFERENCES Authors(AuthorID) ); ``` ### 2. Chèn Dữ liệu (INSERT INTO) Tiếp theo, chúng ta sẽ chèn một số dữ liệu mẫu vào các bảng. ```sql -- Chèn dữ liệu vào bảng Authors INSERT INTO Authors (FirstName, LastName, BirthDate, Country) VALUES ('Nguyễn', 'Nhật Ánh', '1955-05-07', 'Việt Nam'), ('J.K.', 'Rowling', '1965-07-31', 'Anh'), ('Stephen', 'King', '1947-09-21', 'Mỹ'), ('Haruki', 'Murakami', '1949-01-12', 'Nhật Bản'); -- Chèn dữ liệu vào bảng Books INSERT INTO Books (Title, PublicationYear, Genre) VALUES ('Mắt Biếc', 2010, 'Lãng mạn'), ('Tôi Thấy Hoa Vàng Trên Cỏ Xanh', 2015, 'Tuổi thơ'), ('Harry Potter và Hòn đá Phù thủy', 1997, 'Giả tưởng'), ('The Shining', 1977, 'Kinh dị'), ('1Q84', 2009, 'Huyền ảo'); -- Chèn dữ liệu vào bảng BookAuthors để liên kết sách và tác giả INSERT INTO BookAuthors (BookID, AuthorID) VALUES (1, 1), -- Mắt Biếc - Nguyễn Nhật Ánh (2, 1), -- Tôi Thấy Hoa Vàng Trên Cỏ Xanh - Nguyễn Nhật Ánh (3, 2), -- Harry Potter - J.K. Rowling (4, 3), -- The Shining - Stephen King (5, 4); -- 1Q84 - Haruki Murakami -- Một cuốn sách có thể có nhiều tác giả (ví dụ, giả định) -- INSERT INTO BookAuthors (BookID, AuthorID) VALUES (6, 1), (6, 2); -- Nếu có sách thứ 6 đồng tác giả ``` ### 3. Cập nhật Dữ liệu (UPDATE) ```sql -- Cập nhật thông tin tác giả UPDATE Authors SET Country = 'United Kingdom' WHERE FirstName = 'J.K.' AND LastName = 'Rowling'; -- Cập nhật thông tin sách UPDATE Books SET PublicationYear = 2011 WHERE Title = 'Mắt Biếc'; -- Cập nhật liên kết trong BookAuthors (ít phổ biến hơn, thường là xóa rồi chèn lại) -- Ví dụ: Giả sử bạn muốn thay đổi tác giả của một cuốn sách (trong thực tế, bạn sẽ xóa liên kết cũ và thêm liên kết mới) -- UPDATE BookAuthors -- SET AuthorID = <NewAuthorID> -- WHERE BookID = <BookID> AND AuthorID = <OldAuthorID>; ``` ### 4. Xóa Dữ liệu (DELETE) Bạn có thể xóa dữ liệu từ các bảng. ```sql -- Xóa một liên kết sách và tác giả DELETE FROM BookAuthors WHERE BookID = 1 AND AuthorID = 1; -- Xóa liên kết giữa 'Mắt Biếc' và 'Nguyễn Nhật Ánh' -- Xóa một cuốn sách và các liên kết liên quan trong BookAuthors (do ràng buộc khóa ngoại CASCADE DELETE hoặc bạn phải xóa thủ công) DELETE FROM BookAuthors WHERE BookID = 5; -- Xóa tất cả liên kết của sách '1Q84' DELETE FROM Books WHERE BookID = 5; -- Xóa sách '1Q84' -- Xóa một tác giả và các liên kết liên quan trong BookAuthors DELETE FROM BookAuthors WHERE AuthorID = 4; -- Xóa tất cả liên kết của tác giả Haruki Murakami DELETE FROM Authors WHERE AuthorID = 4; -- Xóa tác giả Haruki Murakami ``` ```sql= -- Chọn tất cả tác giả SELECT * FROM Authors; -- Chọn tất cả sách SELECT * FROM Books; -- Chọn tất cả các liên kết sách và tác giả SELECT * FROM BookAuthors; -- Lấy tên sách và tên tác giả của tất cả các cuốn sách SELECT B.Title AS BookTitle, A.FirstName + ' ' + A.LastName AS AuthorName FROM Books AS B INNER JOIN BookAuthors AS BA ON B.BookID = BA.BookID INNER JOIN Authors AS A ON BA.AuthorID = A.AuthorID; -- Lấy tất cả sách của một tác giả cụ thể (ví dụ: Nguyễn Nhật Ánh) SELECT B.Title AS BookTitle, B.PublicationYear, B.Genre FROM Books AS B INNER JOIN BookAuthors AS BA ON B.BookID = BA.BookID INNER JOIN Authors AS A ON BA.AuthorID = A.AuthorID WHERE A.FirstName = 'Nguyễn' AND A.LastName = 'Nhật Ánh'; -- Lấy tất cả tác giả của một cuốn sách cụ thể (ví dụ: 'Mắt Biếc') SELECT A.FirstName + ' ' + A.LastName AS AuthorName, A.BirthDate, A.Country FROM Authors AS A INNER JOIN BookAuthors AS BA ON A.AuthorID = BA.AuthorID INNER JOIN Books AS B ON BA.BookID = B.BookID WHERE B.Title = 'Mắt Biếc'; -- Đếm số lượng sách của mỗi tác giả SELECT A.FirstName + ' ' + A.LastName AS AuthorName, COUNT(BA.BookID) AS NumberOfBooks FROM Authors AS A LEFT JOIN BookAuthors AS BA ON A.AuthorID = BA.AuthorID GROUP BY A.FirstName, A.LastName ORDER BY NumberOfBooks DESC; -- Đếm số lượng tác giả cho mỗi cuốn sách SELECT B.Title AS BookTitle, COUNT(BA.AuthorID) AS NumberOfAuthors FROM Books AS B LEFT JOIN BookAuthors AS BA ON B.BookID = BA.BookID GROUP BY B.Title ORDER BY NumberOfAuthors DESC; ```