Sebagai informasi, solusi ini didasarkan pada perbandingan string, tidak dioptimalkan &tidak dapat menggunakan indeks. Anda harus mempertimbangkan untuk menormalkan tabel Anda secara berbeda. (Lihat Mengelola Data Hirarki di MySQL )
Mengenai beberapa pertanyaan:
Pilih semua anak dari id 9:
Karena Path
kolom tidak menyertakan garis miring awal &akhir, Anda harus menggabungkannya ke jalur:
SELECT *
FROM tester
WHERE CONCAT('/', path, '/') LIKE '%/9/%';
pilih jumlah gabungan dari 9 anak, x dalam level:
Kita perlu mengelompokkan menurut jumlah garis miring di jalur, dikurangi jumlah garis miring di jalur induk:
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
Untuk mempermudah saya menggunakan kueri di atas untuk menampilkan semua level, Jika Anda ingin membatasi kedalaman x level, gunakan WHERE
predikat dari kueri di bawah ini.
pilih ID anak 9 hingga level x, dengan level relatif ke 9:
Kami mencari Path
kolom hingga jumlah x level, sambil mempertimbangkan level orang tua:
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/%'
Langkah-langkah yang kami lakukan:
- Kita perlu mencari tahu seberapa dalam induknya, kita dapat menemukannya dengan menghitung garis miring di jalur induknya. (
LENGTH(p.Path) - LENGTH(REPLACE(p.Path, '/', ''))
) - Kita perlu menambahkan 1 ke angka itu, karena jalur dengan 1 garis miring memiliki kedalaman 2 level.
- Kami menambahkan jumlah x level yang diinginkan.
- Ambil kolom jalur hingga total level, (Gunakan
SUBSTRING_INDEX
fungsi). - Tambahkan garis miring di awal dan akhir.
- Telusuri string terakhir untuk 9.