Không có truy vấn SQL đơn lẻ nào có thể mang lại cho Bạn kết quả được sắp xếp theo cách Bạn mong đợi dựa trên cấu trúc bảng này.
Có hai cách để giải quyết vấn đề:
-
Sử dụng logic ứng dụng bên ngoài (bên ngoài DB) để thực hiện các lệnh gọi đệ quy sẽ phát hiện ra con của mỗi danh mục và xây dựng cây trong ứng dụng.
-
Sử dụng một trong các thuật toán để lưu trữ dữ liệu dạng cây trong cơ sở dữ liệu quan hệ. Một trong các thuật toán đó được gọi là
Modified Preorder Tree Traversalhoặc đơn giản là MPTT.
Giả sử chúng ta sử dụng các cột lft và rgt để duy trì các chỉ mục trái / phải trong quá trình duyệt, khi bạn chèn một danh mục mới, bạn sẽ cần:
-
Nhận thông tin danh mục chính theo Id:
SELECT lft,rgt FROM tbl_categories WHERE categoryId=5Hãy giả sử cho một vấn đề ví dụ, rằng danh mục mẹ cólft=7vàrgt=10(trong trường hợp này nó đã có một con) -
Dành chỗ cho mục nhập mới - chuyển tất cả các bản ghi theo 2 (1 cho lft và 1 cho rgt):
UPDATE tbl_categories SET rgt=rgt+2 WHERE rgt>=10 ORDER BY rgt DESCUPDATE tbl_categories SET lft=lft+2 WHERE lft>=10 ORDER BY lft DESC
Lưu ý ở đây ORDER giảm dần. Dưới dạng lft và rgt được cho là duy nhất, nên tạo UNIQUE ràng buộc chúng và sau đó thứ tự giảm dần trong cập nhật là cần thiết để ngăn các lỗi chính trùng lặp.
-
Đặt
lft=<former parent rgt>vàrgt=<former parent rgt +1>và chèn một bản ghi mới ...INSERT INTO tbl_categories SET categoryName="New Child",parentCategoryId=5,lft=11,rgt=12,...
Bạn có thể tìm thấy các ví dụ chi tiết hơn với mã nếu bạn tìm kiếm MPTT PHP MySQL . Có khá nhiều hướng dẫn về chủ đề này.