【问题标题】:Get furthest parent获得最远的父母
【发布时间】:2020-03-26 23:21:23
【问题描述】:

同一张表的多行可以通过parent_id相互关联。有没有办法获得给定行的最远父级(带有附加条件,如id > 12)?

+----+-----------+
| id | parent_id |
+----+-----------+
| 12 |         1 |
+----------------+
| 13 |        12 |
+----------------+
| 14 |        13 |
+----------------+
| 15 |        14 |
+----------------+
  • 给出的是 id 15
  • 需要 id 13(因为它是 id 大于 12 的最远父级)

是否有任何合理的方法在 1 个语句中执行此操作,而不是一遍又一遍地迭代最近的父级?

【问题讨论】:

  • MySQL 不支持递归查询
  • @EriksKlotins MySQL 8 支持递归查询
  • 使用 8.0 版

标签: mysql sql mysql-8.0


【解决方案1】:

在 MySQL 8.0 中,您可以使用递归查询来做到这一点:

with recursive cte as (
    select id, parent_id, 0 lvl from mytable where id = 15
    union all 
    select c.id, t.parent_id, c.lvl + 1 
    from mytable t
    inner join cte c on c.parent_id = t.id
    where t.parent_id > 12
)
select id, parent_id
from cte c
where c.lvl = (select max(c1.lvl) from cte c1 where c1.id = c.id)

递归 cte 以id = 15 开始,然后沿着关系树直到一个 id 严格小于12 的父级。我们跟踪层次结构中的级别。然后,外部查询过滤具有最高级别的记录。

Demo on DB Fiddle

编号 | parent_id -: | --------: 15 | 13

【讨论】:

    【解决方案2】:

    您可以使用递归 CTE 查找给定 id 值的所有父级,并为它们分配一个 level 以指示它们与原始 id 值的距离。那么这只是找到id 值最大的情况,level 也大于 12:

    WITH RECURSIVE CTE AS
    (
      SELECT id, parent_id, 1 AS level
      FROM data
      WHERE id = 15
      UNION ALL
      SELECT data.id, data.parent_id, CTE.level + 1
      FROM data
      JOIN CTE ON data.id = CTE.parent_id 
      WHERE data.id > 12
    )
    SELECT id
    FROM CTE
    WHERE level = (SELECT MAX(level) FROM CTE)
    

    输出

    13
    

    Demo on dbfiddle

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-09
      • 1970-01-01
      相关资源
      最近更新 更多