Я использовал закрывающую таблицу (этот термин звучит для меня странно ... Я забыл, что / где я слышал, что это называется чем-то еще), но у меня был 3-й столбец "расстояния" между предком и потомком, который позволяет вам различают прямых потомков (детей) и косвенных потомков (внуков и т. д.).
Технически таблица, которую вы перечислили, может записывать данные в ориентированном ациклическом графе, поэтому построение иерархического дерева без дубликатов может быть невозможным.
редактировать:
Если бы я делал запросы в PHP, я бы, вероятно, просто ВЫБЕРИЛ на самой таблице без использования GROUP_CONCAT - вы все равно будете обрабатывать вещи процедурно, так почему бы просто не получить соответствующее подмножество таблицы закрытия в чистом виде?
Обратите внимание, что в таблице закрытия не будет храниться информация о заказе (если это важно).
Если древовидные аспекты этих иерархических данных очень важны, и у вас есть выбор, как хранить данные, рассмотрите модель вложенного множества , которая может поддерживать порядок и намного проще реконструировать дерево.