😃Laravel Has One Through Eloquent Relationship Tutorial

https://viblo.asia/p/tim-hieu-ve-cac-relationships-trong-laravel-oOVlYknrK8W

Đây là một mối quan hệ liên kết các bảng với nhau thông qua một bảng trung gian Ví dụ có 3 bảng:

suppliers
    id - integer
users
    id - integer
    supplier_id - integer
history
    id - integer
    user_id - integer

Mặc dù bảng history không chứ supplier_id nhưng chúng ta vẫn có thể truy cập đến user's history bới mối quan hệ hasOneThrough như sau

Với tham số thứ nhất được truyền vào là tên của model mà chúng ta muốn truy cập, tham số thứ 2 là model trung gian. Chúng ta cũng có thể custom các key liên quan đến mối quan hệ này lần lượt là các tham số sau vào hàm định nghĩa quan hệ.

hai bảng userhistory chúng ta định nghia như bình thường

Từ thiết kế bảng sau

Bài toán 1:

Bài toán:

Mô tả: Giả sử bạn đang quản lý các nhà cung cấp và người dùng trong một công ty phân phối sản phẩm. Mỗi người dùng có thể thực hiện nhiều hoạt động, và mỗi hoạt động này được ghi lại trong bảng histories. Bạn cần thực hiện các yêu cầu sau:

  1. Tìm ra nhà cung cấp có số lượng người dùng nhiều nhất.

  2. Tính tổng số hoạt động (lịch sử) của người dùng thuộc nhà cung cấp đó.

Cấu trúc dữ liệu:

  1. Bảng suppliers:

    • Lưu trữ thông tin về các nhà cung cấp.

    • Các trường: id, name.

  2. Bảng users:

    • Lưu trữ thông tin về người dùng.

    • Các trường: id, supplier_id (chỉ ra nhà cung cấp mà người dùng thuộc về).

  3. Bảng histories:

    • Lưu trữ các hoạt động của người dùng.

    • Các trường: id, user_id, description.

Câu hỏi cần trả lời:

  1. Tìm nhà cung cấp có số lượng người dùng nhiều nhất.

  2. Tính tổng số hoạt động mà các người dùng của nhà cung cấp đó đã thực hiện.


Giải pháp SQL:

Giải thích:

  1. JOIN giữa bảng suppliersusers để kết nối nhà cung cấp với người dùng của họ.

  2. LEFT JOIN với bảng histories để kết nối người dùng với lịch sử hoạt động của họ.

  3. COUNT(u.id) đếm số lượng người dùng của mỗi nhà cung cấp.

  4. COUNT(h.id) đếm số lượng hoạt động của người dùng thuộc mỗi nhà cung cấp.

  5. GROUP BY s.id nhóm kết quả theo nhà cung cấp.

  6. ORDER BY total_users DESC LIMIT 1 sắp xếp theo số lượng người dùng giảm dần và chỉ lấy nhà cung cấp có số lượng người dùng lớn nhất.

Kết quả:

  • supplier_name: Tên nhà cung cấp có số lượng người dùng lớn nhất.

  • total_users: Tổng số người dùng của nhà cung cấp đó.

  • total_histories: Tổng số lịch sử hoạt động của người dùng thuộc nhà cung cấp đó.

Bài toán 2:

Dưới đây là một bài toán cụ thể phù hợp với các bảng histories, suppliers, và users mà bạn đã cung cấp:

Bài toán:

Mô tả: Giả sử bạn đang phát triển một hệ thống quản lý lịch sử hoạt động của các nhà cung cấp và người dùng trong một công ty phân phối sản phẩm. Bạn cần xác định các nhà cung cấp có số lượng người dùng lớn nhất, và tính tổng số lịch sử hoạt động của họ. Đồng thời, bạn cũng cần biết quốc gia của những người dùng này.

Yêu cầu:

  1. Liệt kê tên các nhà cung cấp có số lượng người dùng lớn nhất.

  2. Đối với mỗi nhà cung cấp, tính tổng số lịch sử hoạt động (từ bảng histories) của người dùng liên kết với nhà cung cấp đó.

  3. Lấy thông tin quốc gia của các người dùng liên kết với nhà cung cấp này.

Cấu trúc dữ liệu:

  1. Bảng histories:

    • Lưu trữ các hoạt động lịch sử của người dùng.

    • Mỗi dòng bao gồm id, user_id, description.

  2. Bảng suppliers:

    • Lưu trữ thông tin nhà cung cấp.

    • Mỗi dòng bao gồm id, name (tên nhà cung cấp).

  3. Bảng users:

    • Lưu trữ thông tin người dùng.

    • Mỗi dòng bao gồm id, country_id (ID của quốc gia người dùng), supplier_id (ID của nhà cung cấp mà người dùng thuộc về).

Câu hỏi cần trả lời:

  1. Xác định nhà cung cấp nào có số lượng người dùng lớn nhất?

  2. Tính tổng số lịch sử hoạt động của người dùng thuộc nhà cung cấp đó?

  3. Đưa ra quốc gia của các người dùng đó.


Giải pháp SQL:

Giải thích:

  1. JOIN giữa bảng suppliersusers để lấy thông tin người dùng theo nhà cung cấp.

  2. LEFT JOIN với bảng histories để tính tổng số lịch sử của người dùng.

  3. GROUP_CONCAT để gộp tất cả các quốc gia mà người dùng thuộc vào một chuỗi (nếu có nhiều quốc gia).

  4. COUNT(u.id) đếm tổng số người dùng cho mỗi nhà cung cấp.

  5. SUM(CASE WHEN h.user_id IS NOT NULL THEN 1 ELSE 0 END) tính tổng số lịch sử hoạt động của người dùng.

  6. ORDER BY total_users DESC LIMIT 1 chọn nhà cung cấp có số lượng người dùng lớn nhất.


Kết quả sẽ là thông tin về nhà cung cấp có số lượng người dùng lớn nhất, tổng số lịch sử hoạt động của người dùng thuộc về nhà cung cấp này, và các quốc gia của những người dùng đó.

Last updated