Для простого, возможно, неоптимально-масштабируемого решения, я рекомендую закодировав это с максимальным числом уровней вы будете иметь:
Для 2-й уровней: только
SELECT p2.name as `Parent name`, p1.*
FROM categories p1
LEFT JOIN categories p2 on p1.categories_id = p2.id
Вы действительно с просьбой о сортировке, так что я рекомендовал бы генерировать «путь» -like строки: (см ниже пример вывод этого запроса)
SELECT Concat(If(isnull(p2.name),"",Concat("/",p2.name)),"/",p1.name) as `generated path`, p2.name as `Parent name`, p1.*
FROM categories p1
LEFT JOIN categories p2 on p1.parent_id = p2.id
order by `generated path`
для 3-й уровней, м ух ваши данные не имеют этого еще - путь опущены, потому что он получит некрасиво :)
SELECT p3.name as `Grandparent name`, p2.name as `Parent name`, p1.*
FROM categories p1
LEFT JOIN categories p2 on p1.categories_id = p2.id
LEFT JOIN categories p3 on p2.categories_id = p3.id
Более полное решение для быстрого выбора всех элементов в определенной категории на любом уровне, который требует некоторой работы над все пишет, реализует 'right' and 'left' numbering concept. Но дальнейшее обсуждение этого вопроса, безусловно, выходит за рамки того, что вы просите. Тем не менее, это единственный хороший способ в моем опыте сделать такую таблицу саморегуляции очень полезной, если она станет большой (возможно, после 1000+ строк с 3 до 10 уровней).
Приложение: Пример вывода из второго запроса:
generated path Parent name id name parent_id
----------------------------------------------------------------------------
/apple 1 apple 0
/apple/lisa apple 5 lisa 1
/apple/mac apple 2 mac 1
/atari 3 atari 0
/atari/st atari 4 st 3
@Fo - Кажется, опечатка? Atari следует указывать сразу после яблока – ajreal 2010-11-23 18:08:06
Нет, дети яблока должны быть перечислены после яблока, затем атари, потом дети атари. (Лиза была компьютером Apple, выпущенным до Macintosh) – 2010-11-23 18:14:44
Как насчет внука? Я полагаю, что их также следует сортировать (то есть: рекурсивно)? – Tomalak 2010-11-23 18:23:04