念のために言っておきますが、これらのソリューションは文字列の比較に基づいており、最適化されておらず、インデックスを使用できません。テーブルを別の方法で正規化することを検討する必要があります。 (MySQLでの階層データの管理 を参照してください。 )
いくつかの質問について:
ID 9のすべての子を選択します:
Path
以降 列には先頭と末尾のスラッシュが含まれていません。パスに連結する必要があります:
SELECT *
FROM tester
WHERE CONCAT('/', path, '/') LIKE '%/9/%';
9の子の総数を選択し、xレベルの深さ:
パス内のスラッシュの数から親パス内のスラッシュの数を引いた数でグループ化する必要があります:
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
簡単にするために、上記のクエリを使用してすべてのレベルを表示しました。xレベルを深く制限する場合は、WHERE
を使用します。 以下のクエリからの述語。
9の子IDをxレベルまで選択し、レベルは9を基準にします:
Path
を検索します 親のレベルを考慮しながら、xレベルまでの列:
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/%'
私たちが取っているステップ:
- 親の深さを知る必要があります。親のパスのスラッシュを数えることで、それを見つけることができます。 (
LENGTH(p.Path) - LENGTH(REPLACE(p.Path, '/', ''))
) - スラッシュが1つのパスは2レベルの深さであるため、その数に1を追加する必要があります。
- 必要なレベルのx個を追加します。
- パス列をレベル合計まで取得します(
SUBSTRING_INDEX
機能)。 - 先頭と末尾のスラッシュを追加します。
- 最後の文字列で9を検索します。