为了账号安全,请及时绑定邮箱和手机立即绑定

MySQL的按优先级等效连接

MySQL的按优先级等效连接

摇曳的蔷薇 2019-10-21 12:42:55
所有,我在表中有三个字段,用于定义MySQL数据库5.0版中存在的父子关系。表名是tb_Tree,它具有以下数据:Table Name: tb_TreeId | ParentId | Name--------------------1  | 0        | Fruits2  | 0        | Vegetables3  | 1        | Apple4  | 1        | Orange5  | 2        | Cabbage6  | 2        | Eggplant如果指定了ParentId,如何编写查询以获取所有子项。请注意,给出的表条目只是示例数据,它们可以有更多行。Oracle有一个“ CONNECT BY PRIOR”子句,但是我没有找到与MySQL类似的东西。任何人都可以请教吗?谢谢
查看完整描述

3 回答

?
冉冉说

TA贡献1877条经验 获得超1个赞

MySQL不支持递归查询,因此您必须采用困难的方式:


选择您的根在ParentID = X哪里的行X。

Id从(1)收集值。

对Id(2)中的每个重复(1 )。

继续手动递归,直到找到所有叶子节点。

如果您知道最大深度,则可以将表连接到自身(使用LEFT OUTER JOINs),使其达到最大可能深度,然后清除NULL。


您也可以将树的表示形式更改为嵌套集。


查看完整回答
反对 回复 2019-10-21
?
POPMUISE

TA贡献1765条经验 获得超5个赞

这是一个旧主题,但是由于我在另一个论坛中遇到了这个问题,所以我想在这里添加它。对于这种情况,我创建了一个存储过程,该存储过程经过硬编码以处理特定情况。当然这样做确实有一些缺点,因为并非所有用户都可以随意创建存储过程。


考虑具有节点和子节点的下表:


CREATE TABLE nodes (

       parent INT,

       child INT

);


INSERT INTO nodes VALUES

       ( 5,  2), ( 5, 3),

       (18, 11), (18, 7),

       (17,  9), (17, 8),

       (26, 13), (26, 1), (26,12),

       (15, 10), (15, 5),       

       (38, 15), (38, 17), (38, 6),

       (NULL, 38), (NULL, 26), (NULL, 18);

使用此表,以下存储过程将计算一个由所提供节点的所有后代组成的结果集:


delimiter $$

CREATE PROCEDURE find_parts(seed INT)

BEGIN

  -- Temporary storage

  DROP TABLE IF EXISTS _result;

  CREATE TEMPORARY TABLE _result (node INT PRIMARY KEY);


  -- Seeding

  INSERT INTO _result VALUES (seed);


  -- Iteration

  DROP TABLE IF EXISTS _tmp;

  CREATE TEMPORARY TABLE _tmp LIKE _result;

  REPEAT

    TRUNCATE TABLE _tmp;

    INSERT INTO _tmp SELECT child AS node

      FROM _result JOIN nodes ON node = parent;


    INSERT IGNORE INTO _result SELECT node FROM _tmp;

  UNTIL ROW_COUNT() = 0

  END REPEAT;

  DROP TABLE _tmp;

  SELECT * FROM _result;

END $$

delimiter ;


查看完整回答
反对 回复 2019-10-21
?
守候你守候我

TA贡献1802条经验 获得超10个赞

下面select列出了所有植物及其parentid最高4级(当然,您可以扩展该级):


select id, name, parentid

,(select parentid from tb_tree where id=t.parentid) parentid2

,(select parentid from tb_tree where id=(select parentid from tb_tree where id=t.parentid)) parentid3

,(select parentid from tb_tree where id=(select parentid from tb_tree where id=(select parentid from tb_tree where id=t.parentid))) parentid4 

from tb_tree t

然后您可以使用此查询获取最终结果。例如,您可以通过以下sql获取“水果”的所有子代:


select id ,name from (

    select id, name, parentid

    ,(select parentid from tb_tree where id=t.parentid) parentid2

    ,(select parentid from tb_tree where id=(select parentid from tb_tree where id=t.parentid)) parentid3

    ,(select parentid from tb_tree where id=(select parentid from tb_tree where id=(select parentid from tb_tree where id=t.parentid))) parentid4 

    from tb_tree t) tt

where ifnull(parentid4,0)=1 or ifnull(parentid3,0)=1 or ifnull(parentid2,0)=1 or ifnull(parentid,0)=1


查看完整回答
反对 回复 2019-10-21
  • 3 回答
  • 0 关注
  • 437 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信