表结构

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

我有一个 id“852”,它位于树形菜单的中间,但我想获取所有先前的相关行和下一个相关行,所以我想获得以下结果:

帮我!> 喜欢 > 没用 > 尝试一下 > 完成。:) (这个结果在 php 循环之后显示,但从起始 ID 1 和回复 ID 0 开始循环。

笔记:2200 id 没有显示在结果中,因为它不属于该组。

有帮助吗?

解决方案

有几种替代方法可以使层次结构信息更容易在 SQL 中使用:

  • 通用表表达式 (根据 SQL-2003 标准)支持针对您正在使用的父 ID 类型的数据进行递归 SQL 查询。目前为止,MySQL还不支持该功能。PostgreSQL 8.4、Microsoft SQL Server 和 IBM DB2 是支持 CTE 语法的 RDBMS 品牌的示例。Oracle 还拥有支持递归查询的 SQL 语法专有扩展。

  • 嵌套集 (@phantombrain 提到的左/右解决方案)是 Joe Celko 的书“Trees and Hierarchies in SQL for Smarties”以及互联网上的许多文章和博客文章中详细介绍的解决方案。

  • 路径枚举 (又名物化路径)在层次结构中的每一行中存储一个字符串,以记录该行的祖先的路径。将此与 LIKE 查询以将路径字符串与其祖先路径和后代路径进行比较。

  • 关闭表 (又名传递闭包关系)使用第二个表来存储所有祖先-后代关系,而不仅仅是您正在使用的设计中的直接父级关系。一旦存储了所有路径,许多类型的查询就会变得更容易。

  • 混合解决方案 也存在。例如,像您正在做的那样存储直接父 ID,但也存储树的根。现在,您可以获取同一层次结构中的所有其他行,将它们提取到应用程序代码中,并使用传统数据结构对树进行排序。

其他提示

假设这些菜单项和不是很动态的,比如一个论坛,我会建议模式更改为每个项目添加左边和右边的值。左,右值之间的ID是要查询的节点的所有孩子。因此,很容易做一个查询来获取左/右值,和第二查询得到子项目。

请参阅 http://www.sitepoint.com/print/hierarchical-data -database / 了解详情

递归是最优雅的方式来做到这一点,但我不认为MySQL支持它的自定义函数或storedprocedures。我建议一环到一个临时表或表变量,让您的ID,然后加入表和结果查询回来。我不知道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