Вопрос

структура таблицы

id    |    message    |    reply_id
1     |    help me!   |    0
434   |    love to    |    1
852   |    didn't work |    434
0110  |    try this   |    852
2200  |    this wont  |    0
5465  |    done. :)   |    0110

у меня есть идентификатор «852», который находится в середине древовидного меню, но я хочу получить все предыдущие и следующие связанные строки, поэтому я хочу получить следующие результаты:

Помоги мне!> с удовольствием > не получилось > попробовать > готово.:) (этот результат выглядит так после цикла php, но цикл начинается с идентификатора стартера 1 с идентификатором ответа 0.

ПРИМЕЧАНИЕ:Идентификатор 2200 не появился в результате, поскольку он не входит в группу.

Это было полезно?

Решение

Существует несколько вариантов упрощения работы с иерархической информацией в SQL:

  • Общие табличные выражения (согласно стандарту SQL-2003) поддерживают рекурсивные запросы SQL к используемым вами типам данных родительского идентификатора.Пока что MySQL не поддерживает эту функцию.PostgreSQL 8.4, Microsoft SQL Server и IBM DB2 являются примерами брендов СУБД, поддерживающих синтаксис CTE.Oracle также имеет собственное расширение синтаксиса SQL, поддерживающее рекурсивные запросы.

  • Вложенные наборы (левое/правое решение, о котором упоминает @phantombrain) — это решение, подробно описанное в книге Джо Селко «Деревья и иерархии в SQL для Smarties», а также в многочисленных статьях и сообщениях в блогах в Интернете.

  • Перечисление путей (также известный как «Материализованный путь») сохраняет строку в каждой строке иерархии, чтобы отметить путь предков этой строки.Объедините это с LIKE запросы для сравнения строки пути с путями ее предков и потомков.

  • Таблица закрытия (также известное как отношение транзитивного замыкания) использует вторую таблицу для хранения всех отношений «предок-потомок», а не только непосредственного родителя, как в используемом вами проекте.Многие типы запросов становятся проще, когда все пути сохранены.

  • Гибридные решения также существуют.Например, сохраните непосредственный родительский идентификатор, как вы это делаете, а также корень дерева.Теперь вы можете получить все остальные строки в той же иерархии, извлечь их в код приложения и отсортировать дерево с помощью обычных структур данных.

Другие советы

Предполагая, что это пункты меню, а не что-то очень динамичное, например форум, я бы рекомендовал изменить схему, добавив значения левого и правого угла для каждого элемента.Все идентификаторы между левым и правым значениями являются дочерними элементами запрашиваемого узла.Таким образом, можно легко выполнить один запрос для получения значений левого и правого полей, а второй запрос — для получения подэлементов.

Видеть http://www.sitepoint.com/print/hierarchical-data-database/ Чтобы получить больше информации

Рекурсия — самый элегантный способ сделать это, но я не думаю, что mySql поддерживает ее в пользовательских функциях или хранимых процедурах.Я бы предложил выполнить цикл во временной таблице или табличной переменной, чтобы получить ваши идентификаторы, затем присоединиться к таблице и запросить результаты обратно.Я не очень хорошо знаю mySql, так что это не проверено, но что-то в этом роде.

CREATE TEMPORARY TABLE tbl (myid int, ViewOrder int); 
Set @ifoundID=IdYourLookingFor;
Set @iStartID=@ifoundID;
Set @iOrder=0;
INSERT INTO tbl(myid,ViewOrder)VALUES(@ifoundID,@iOrder);

BEGIN --get the ones going up
 WHILE (@ifoundID Is Not Null) DO 
  SELECT @ifoundID=reply_id FROM YourTable WHERE id=@ifoundID; --find the next id
  SET @iOrder1=@iOrder-1; --increment the order
  INSERT INTO tbl(myid,ViewOrder)VALUES(@ifoundID,@iOrder);--save the nextid
 END WHILE;
END

Set @ifoundID=@iStartID;
BEGIN --get the ones going down
 WHILE (@ifoundID Is Not Null) DO 
  SELECT @ifoundID=id FROM YourTable WHERE reply_id=@ifoundID; --find the next id
  SET @iOrder1=@iOrder+1; --increment the order
  INSERT INTO tbl(myid,ViewOrder)VALUES(@ifoundID,@iOrder);--save the nextid
 END WHILE;
END

SELECT * FROM tbl INNER JOIN YourTable ON tbl.myid=YourTable.id ORDER BY ViewOrder

надеюсь, это поможет

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top