Самый простой и вместе с тем гениальный способ построения дерева, это не использовать никакие id, parent_id, не использовать никакие id_left, id_right смещения, какие там ещё виды дерева бывают...
Самый верный, ИМХО, способ, — сохранять полный путь, который проходит каждое сообщение.
Написали сообщение с ID = 1, затем на него ответили, ответ с ID = 2, а его путь, коли оно является ответом на первое сообщение, будет: «1 2».
Таблица вида
comment_id | thread_path
------------------------
1 | 1
2 | 1.2
3 | 1.3
Где количеством отсутступов «вправо» в дереве является количество ответов в thread_path, и всего один SQL-запрос для вывода всего, с группировкой по дереву.
<?php $try = $dbh->query('SELECT * FROM forum GROUP BY thread_path'); ?>
<?php while ($row = $try->fetchArray()): extract($row); unset($row); ?>
<?php echo str_repeat(' ', substr_count($thread_path, '.')); ?>
<?php echo $comment_text; ?>
<?php endwhile; ?>
Рабочий пример: http://spfng.com/forum/
Теперь вопрос. Я не знаю как сделать, чтобы выводить сообщения в обратном порядке, но при этом целиком сохранялось дерево ответов.
Подскажите? Как сделать, чтобы все корневые сообщения, у которых thread_path = comment_id, выводились в обратном порядке, ORDER BY comment_id DESC
, но при этом все другие сообщения, которые являются ответами на корневые (которые начинаются как thread_path LIKE comment_id || ".%"
), не меняли свой порядок вывода, а оставались как есть сейчас, ORDER BY comment_id ASC
. Как-то так...
Это реально в один SQL-запрос уместить?