【问题标题】:Join parent to child node in hierarchical table structure在分层表结构中将父节点连接到子节点
【发布时间】:2017-09-13 21:30:00
【问题描述】:

我有以下用于抓取树节点及其父节点的 SQL:

SELECT 
        c.id
    ,   c.tag
    ,   (
            SELECT 
                    s.id
            FROM treeTable s 
            WHERE s.lft < c.lft AND s.rgt > c.rgt
            ORDER BY s.rgt - c.rgt ASC
            LIMIT 1
        ) AS parent
FROM treeTable c;

问题是我也想在表中使用s.tag,但是我不能从子查询中选择两列。我该如何重构这个 SQL 以便能够选择两列?

我查看了很多关于可能尝试 LEFT JOIN 的资源,但无法使任何工作。由于需要在子查询中使用 ORDER BY 和 LIMIT,我想不出一个简单的分组操作

编辑:表的结构如下:

Field     Type              Collation          Null    Key     Default  Extra           Privileges                       Comment  
--------  ----------------  -----------------  ------  ------  -------  --------------  -------------------------------  ---------
id        int(10)           (NULL)             NO      PRI     (NULL)   auto_increment  select,insert,update,references                    
tag       varchar(255)      latin1_swedish_ci  NO              (NULL)                   select,insert,update,references           
lft       int(11)           (NULL)             NO      MUL     (NULL)                   select,insert,update,references           
rgt       int(11)           (NULL)             NO      MUL     (NULL)                   select,insert,update,references           

【问题讨论】:

    标签: mysql sql hierarchical-data


    【解决方案1】:

    试试这个,使用两个低效的子选择

    SELECT 
    c.id,
    c.tag,
    (
        SELECT 
            s.id
        FROM treeTable s 
        WHERE s.lft < c.lft AND s.rgt > c.rgt
        ORDER BY s.rgt - c.rgt ASC
        LIMIT 1
    ) AS parent, 
    (
        SELECT 
            s.tag
        FROM treeTable s 
        WHERE s.lft < c.lft AND s.rgt > c.rgt
        ORDER BY s.rgt - c.rgt ASC
        LIMIT 1
    ) AS parent_tag
    FROM treeTable c;
    

    这似乎在逻辑上是正确的。无法测试抱歉。在这种情况下,如果您确实经常使用它,您应该重构并设计一个具有更好定义的父子链接的表

    【讨论】:

    • 这个解决方案效率低下,我查询的表有数百万个条目并且还在不断增加。我不想每个查询都有两个子查询。告诉我重新设计设计也不是一个有效的答案,因为该表的设计性能非常好。不过,我感谢您愿意提供帮助,谢谢!
    • 我完全理解。您的案例中的困难源于这样一个事实,即您与一个范围链接并使用技巧(LIMIT 1)来获得在大多数情况下应该是 JOIN 的最佳结果。我最初编写了一个 JOIN 版本,其距离 (s.rgt - c.rgt) 为 MIN,但不能保证获得 s.id 和 s.tag ...。希望您能找到解决方案。
    猜你喜欢
    • 1970-01-01
    • 2021-02-25
    • 1970-01-01
    • 2011-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    相关资源
    最近更新 更多