# ba bảng có mối quan hệ một-nhiều giữa các bảng

Dưới đây là ví dụ về ba bảng có mối quan hệ một-nhiều giữa các bảng. Mỗi bảng sẽ có dữ liệu cụ thể và mối quan hệ thực tế để giải quyết bài toán:

#### Bảng 1: `categories`

**Mô tả:**\
Bảng này lưu trữ các danh mục sản phẩm (ví dụ: điện thoại, máy tính, sách, v.v.).

```
CREATE TABLE categories (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL
);
```

**Dữ liệu ví dụ:**

| id | name       |
| -- | ---------- |
| 1  | Điện thoại |
| 2  | Máy tính   |
| 3  | Sách       |

#### Bảng 2: `products`

**Mô tả:**\
Bảng này lưu trữ thông tin về sản phẩm. Mỗi sản phẩm thuộc một danh mục trong bảng `categories`. Mối quan hệ ở đây là **một-nhiều** giữa `categories` và `products`, tức là mỗi danh mục có thể có nhiều sản phẩm, nhưng mỗi sản phẩm chỉ thuộc về một danh mục.

```
CREATE TABLE products (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    category_id INT,
    price DECIMAL(10, 2),
    FOREIGN KEY (category_id) REFERENCES categories(id)
);
```

**Dữ liệu ví dụ:**

| id | name             | category\_id | price |
| -- | ---------------- | ------------ | ----- |
| 1  | iPhone 13        | 1            | 1000  |
| 2  | Galaxy S21       | 1            | 950   |
| 3  | Dell XPS 13      | 2            | 1200  |
| 4  | Tìm lại tuổi trẻ | 3            | 20    |

#### Bảng 3: `orders`

**Mô tả:**\
Bảng này lưu trữ thông tin về các đơn hàng. Mỗi đơn hàng có thể chứa nhiều sản phẩm, và mỗi sản phẩm lại thuộc một danh mục (thông qua bảng `products`). Mối quan hệ giữa `orders` và `products` là mối quan hệ **nhiều-nhiều** thông qua bảng phụ (junction table).

```
CREATE TABLE orders (
    id INT AUTO_INCREMENT PRIMARY KEY,
    order_date DATE,
    total_price DECIMAL(10, 2)
);
```

**Dữ liệu ví dụ:**

| id | order\_date | total\_price |
| -- | ----------- | ------------ |
| 1  | 2026-04-01  | 2150.00      |
| 2  | 2026-04-02  | 1200.00      |

#### Bảng 4: `order_items` (Junction table)

**Mô tả:**\
Bảng này lưu trữ các sản phẩm trong mỗi đơn hàng. Mối quan hệ giữa `orders` và `products` là mối quan hệ **nhiều-nhiều**, và bảng `order_items` giúp lưu trữ thông tin này, với mỗi dòng là một sản phẩm trong một đơn hàng cụ thể.

```
CREATE TABLE order_items (
    order_id INT,
    product_id INT,
    quantity INT,
    price DECIMAL(10, 2),
    PRIMARY KEY (order_id, product_id),
    FOREIGN KEY (order_id) REFERENCES orders(id),
    FOREIGN KEY (product_id) REFERENCES products(id)
);
```

**Dữ liệu ví dụ:**

| order\_id | product\_id | quantity | price |
| --------- | ----------- | -------- | ----- |
| 1         | 1           | 1        | 1000  |
| 1         | 2           | 1        | 950   |
| 2         | 3           | 1        | 1200  |

#### Mối quan hệ giữa các bảng:

* **`categories` ↔ `products`**: Mối quan hệ một-nhiều (1-n) - Một danh mục có thể có nhiều sản phẩm.
* **`orders` ↔ `products`**: Mối quan hệ nhiều-nhiều (n-n) - Một đơn hàng có thể chứa nhiều sản phẩm, và một sản phẩm có thể thuộc nhiều đơn hàng thông qua bảng `order_items`.

#### Bài toán thực tế:

**Mô tả:**\
Giả sử bạn cần báo cáo về các đơn hàng, trong đó mỗi đơn hàng có thể chứa nhiều sản phẩm thuộc các danh mục khác nhau. Bạn muốn biết số lượng và tổng giá trị của sản phẩm theo từng danh mục trong mỗi đơn hàng.

**Yêu cầu:**

1. Tính tổng giá trị của sản phẩm cho từng danh mục trong mỗi đơn hàng.
2. Liệt kê tên danh mục và tổng số tiền cho từng đơn hàng.

#### Giải pháp SQL:

```
SELECT 
    o.id AS order_id,
    c.name AS category_name,
    SUM(oi.quantity * oi.price) AS total_category_price
FROM 
    orders o
JOIN 
    order_items oi ON o.id = oi.order_id
JOIN 
    products p ON oi.product_id = p.id
JOIN 
    categories c ON p.category_id = c.id
GROUP BY 
    o.id, c.id
ORDER BY 
    o.id, c.name;
```

#### Giải thích:

1. **JOIN** giữa các bảng `orders`, `order_items`, `products` và `categories` để kết nối các đơn hàng, sản phẩm và danh mục.
2. **SUM(oi.quantity \* oi.price)** tính tổng giá trị của sản phẩm theo từng danh mục trong mỗi đơn hàng.
3. **GROUP BY o.id, c.id** nhóm theo đơn hàng và danh mục sản phẩm.
4. **ORDER BY o.id, c.name** sắp xếp kết quả theo đơn hàng và tên danh mục.

#### Kết quả mong đợi:

| order\_id | category\_name | total\_category\_price |
| --------- | -------------- | ---------------------- |
| 1         | Điện thoại     | 1950.00                |
| 1         | Máy tính       | 950.00                 |
| 2         | Máy tính       | 1200.00                |

***

Đây là một bài toán thực tế về quản lý đơn hàng và sản phẩm, sử dụng mối quan hệ một-nhiều và nhiều-nhiều giữa các bảng để theo dõi danh mục sản phẩm trong mỗi đơn hàng.
