【问题标题】:Ordering by criteria - Using Recursive CTE按标准排序 - 使用递归 CTE
【发布时间】:2020-07-18 06:52:29
【问题描述】:

我有一个 sql 表,我想按照每个元素在其正下方的行中具有代码为 parentCode 的元素的方式对其进行排序。为了更清楚地看这个例子:

            id      name         code               parentCode

parent1      1      "element1"  "parent1code"       null
parent2      2      "element2"  "parent2code"       null
children1    3      "element3"  "children1code"    "parent1Code"
children2    4      "element4"  "children2code"    "parent2Code"
children3    5      "element5"  "children3code"    "parent1Code"

等等..

我想这样订购:

  parent1    
   children1    
   children3 
 parent2   
   children2

PS:此层次结构中的层数不确定(子也可以是父)

【问题讨论】:

    标签: mysql sql common-table-expression recursive-query


    【解决方案1】:

    这在 MySQL 中有点棘手。基本思想是使用递归 CTE 构建到顶部的路径,然后按路径排序。但是,您希望路径中的每个标识符都具有恒定长度以避免排序问题。而且,MySQL 不支持数组,所以这一切都必须进入一个字符串。

    所以,我会推荐这样的东西:

    with recursive cte as (
          select id, name, code, parent, 
                 cast(lpad(id, 4, '0') as char(255)) as path
          from sample
          where parent is null 
          union all
          select s.id, s.name, s.code, s.parent, 
                 concat(cte.path, '->', lpad(s.id, 4, '0'))
          from cte join
               sample s 
               on s.parent = cte.code
         )
    select *
    from cte
    order by path;
    

    Here 是一个 dbfiddle。

    注意:这会将 id 扩展为四个字符。这很容易修改。

    【讨论】:

      【解决方案2】:

      你应该使用Recursive Common Table Expression来实现这个

      试试这个:

      with recursive cte(id, name, code, parent, key_) as (
      
      select id, name, code, parent, array[id] as key_   
      from sample where parent is null
      
      union all
                                                                                     
      select t1.id, t1.name, t1.code, t1.parent, t2.key_ || t1.id 
      from sample t1 
      inner join cte t2 on t1.parent=t2.id
      )
      
      select id, name, code, parent from cte order by key_ 
      

      DEMO on Fiddle

      编辑

      根据您的评论详细信息修改

      with recursive cte(id, name, code,parent,key_) as (
      select id,name,code,parent,array[code] as key_   from sample where parent is null
        union all
                                                                                     
      select t1.id,t1.name,t1.code,t1.parent,t2.key_ || t1.parent from sample t1 inner join cte t2 on t1.parent=t2.code
      )
      
      select id, name, code,parent from cte order by key_ 
      

      DEMO

      【讨论】:

      • 为什么父列中有数字?
      • 你可以使用你想要的。理想情况下,它必须是表 id
      【解决方案3】:
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-19
      • 2010-10-08
      • 1970-01-01
      • 1970-01-01
      • 2020-03-31
      • 2012-04-23
      • 2011-02-12
      相关资源
      最近更新 更多