### 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;
```