问题 MySQL中的分层查询


我试图找到任何深度的特定领域的所有父母,祖父母等。例如,给定以下结构,如果我提供5,则返回的值应为1,2,3和4。

| a  | b  |
-----------
| 1  | 2  |
| 2  | 3  |
| 3  | 4  |
| 4  | 5  |
| 3  | 6  |
| 4  | 7  |

我该怎么办?


6289
2017-11-12 11:37


起源

您必须为此更改架构。读 @BillKarwin的演讲标题为 使用SQL和PHP的分层数据模型,关于不同的模型以及如何实现它们。 - Shef
@Shef:我应该在架构中做出哪些更改,以及如何编写查询。
@BillKarwin:在您的ppt中,您已经提到过使用mysql无法完成上述逻辑。是吗?
不在单个纯SQL查询中,没有。除非你使用像@ Quassnoi这样的用户变量技巧。 - Bill Karwin


答案:


SELECT  @id :=
        (
        SELECT  senderid
        FROM    mytable
        WHERE   receiverid = @id
        ) AS person
FROM    (
        SELECT  @id := 5
        ) vars
STRAIGHT_JOIN
        mytable
WHERE   @id IS NOT NULL

23
2017-11-13 13:13



哇...如果你使用太多,可能会很危险,就像在一个大网站上一样? - Wiliam
@Wiliam:它不是升级安全的,因为 MySQL 没有明确定义会话变量行为。但是,这是在查询中及时处理邻接列表的唯一方法。 - Quassnoi
仅供参考(因为“危险”可能意味着任何事情),有人可以详细说明这会使它变得危险吗?什么会导致它/不危险? - Mike
@MichaelJMulligan:这个查询可以随时停止工作,因为它依赖于某些行为(重新评估 @id 为了 WHERE 每一行的条件,单一的评价 @id := 5 在查询的开头等),MySQL文档中没有指定,并且可能随着任何次要版本升级而改变。即使没有版本升级,您也无法确定这些是如何工作的。整个查询基本上都是一个黑客。 - Quassnoi
@Shawn: explainextended.com/2009/07/20/... (我是作者)。请注意,这是一个丑陋的黑客攻击,可能并且可能会在未来的MySQL版本中停止工作。 - Quassnoi


以下答案不是MYSQL,而是使用PHP。这个答案对于在搜索过程中最终出现在这个页面上的所有人都很有用(就像我一样),但不仅限于使用MYSQL。

如果您的数据库具有未知深度的嵌套结构,则可以使用递归循环打印出内容:

function goDownALevel($parent){
     $children = $parent->getChildren(); //underlying SQL function
     if($children != null){
          foreach($children as $child){
                //Print the child content here
                goDownALevel($child);
          }
     }
}

此功能也可以用Javascript等任何其他语言重写。


-7
2018-01-24 08:58