Xin lưu ý rằng các giải pháp này dựa trên so sánh chuỗi, không được tối ưu hóa và không thể sử dụng chỉ mục. bạn nên xem xét việc bình thường hóa các bảng của mình theo cách khác. (Xem Quản lý dữ liệu phân cấp trong MySQL )
Về một số câu hỏi:
Chọn tất cả các phần tử con của id 9:
Kể từ Path
cột không bao gồm dấu gạch chéo đầu &cuối, bạn cần nối chúng với đường dẫn:
SELECT *
FROM tester
WHERE CONCAT('/', path, '/') LIKE '%/9/%';
chọn tổng số con của 9, sâu x cấp:
Chúng ta cần nhóm theo số dấu gạch chéo trong đường dẫn, trừ đi số dấu gạch chéo trong đường dẫn chính:
SELECT (LENGTH(c.Path) - LENGTH(REPLACE(c.Path, '/', '')))
- (LENGTH(p.Path) - LENGTH(REPLACE(p.Path, '/', ''))) AS Level,
COUNT(*)
FROM tester c
JOIN tester p ON c.Parent = p.ID
WHERE CONCAT('/', path, '/') LIKE '%/9/%';
GROUP BY 1
Để đơn giản, tôi đã sử dụng truy vấn ở trên để hiển thị tất cả các cấp, Nếu bạn muốn giới hạn sâu x cấp, hãy sử dụng WHERE
vị từ từ truy vấn bên dưới.
chọn id của trẻ em 9 xuống cấp x, với cấp tương đối với 9:
Chúng tôi tìm kiếm Path
lên đến một số cấp x, trong khi cân nhắc cấp phụ huynh:
SELECT c.*
FROM tester c
JOIN tester p ON c.Parent = p.ID
WHERE CONCAT(
'/',
SUBSTRING_INDEX(
Path,
'/',
(LENGTH(p.Path) - LENGTH(REPLACE(p.Path, '/', ''))) + 4
),
'/') LIKE '%/9/%'
Các bước chúng tôi đang thực hiện:
- Chúng tôi cần tìm hiểu độ sâu của đường phụ huynh, chúng tôi có thể tìm thấy điều đó bằng cách đếm các dấu gạch chéo trên đường dẫn của phụ huynh. (
LENGTH(p.Path) - LENGTH(REPLACE(p.Path, '/', ''))
) - Chúng tôi cần thêm 1 vào số đó vì đường dẫn có 1 dấu gạch chéo sâu 2 cấp.
- Chúng tôi thêm x số cấp độ mong muốn.
- Lấy cột đường dẫn lên đến tổng cấp, (Sử dụng
SUBSTRING_INDEX
chức năng). - Thêm dấu gạch chéo ở đầu và ở cuối.
- Tìm kiếm chuỗi cuối cùng cho 9.