SQL树路径结构长度

时间:2017-04-25 20:00:37

标签: sql oracle recursion

我有以下数值:

Id | Sum | Tree_path_structure
 1 | 10  | /1/2
 2 | 30  | /1/3/4
 3 | 40  | /1/3/5
 4 | 50  | /1/6

对于最长的树路径,在示例中,id(2,3)中的id应该返回小的总和,输出应该是:

Id | Sum | Tree_path_structure
 1 | 10  | /1/2
 2 | 30  | /1/3/4
 4 | 50  | /1/6

我想基于树路径结构长度的SQL将返回最小的和值。

1 个答案:

答案 0 :(得分:0)

Oracle安装程序

CREATE TABLE your_table ( Id, SUm, Tree_path_structure ) AS
  SELECT 1, 10, '/1/2'   FROM DUAL UNION ALL
  SELECT 2, 30, '/1/3/4' FROM DUAL UNION ALL
  SELECT 3, 40, '/1/3/5' FROM DUAL UNION ALL
  SELECT 4, 50, '/1/6'   FROM DUAL;

<强>查询

SELECT id,
       sum,
       tree_path_structure
FROM   (
  SELECT id,
         sum,
         tree_path_structure,
         CASE
           WHEN is_Max_Depth = 0
             OR sum = MIN( sum ) OVER ( PARTITION BY is_Max_Depth ) 
           THEN 0
           ELSE 1
         END AS is_Max_Depth_With_Higher_sum
  FROM   (
    SELECT id,
           sum,
           tree_path_structure,
           CASE depth WHEN MAX( depth ) OVER () THEN 1 ELSE 0 END AS is_Max_Depth
    FROM   (
      SELECT ID,
             SUM,
             Tree_Path_Structure,
             LENGTH( Tree_Path_Structure ) - LENGTH( REPLACE( Tree_Path_Structure, '/' ) )
               AS depth
      FROM   your_table
    ) t
  )
)
WHERE is_Max_Depth_With_Higher_sum = 0;

<强>输出

        ID        SUM TREE_P
---------- ---------- ------
         1         10 /1/2  
         4         50 /1/6  
         2         30 /1/3/4

<强>更新

SELECT id,
       sum,
       tree_path_structure
FROM   (
  SELECT id,
         sum,
         tree_path_structure,
         CASE
           WHEN is_Max_Depth = 0
             OR sum = MIN( sum ) OVER ( PARTITION BY root, is_Max_Depth ) 
           THEN 0
           ELSE 1
         END AS is_Max_Depth_With_Higher_sum
  FROM   (
    SELECT id,
           sum,
           tree_path_structure,
           root,
           CASE depth WHEN MAX( depth ) OVER ( PARTITION BY root ) THEN 1 ELSE 0 END AS is_Max_Depth
    FROM   (
      SELECT ID,
             SUM,
             Tree_Path_Structure,
             SUBSTR( Tree_Path_Structure, 1, INSTR( Tree_Path_Structure, '/', 1, 2 ) )
               AS root,
             LENGTH( Tree_Path_Structure ) - LENGTH( REPLACE( Tree_Path_Structure, '/' ) )
               AS depth
      FROM   your_table
    ) t
  )
)
WHERE is_Max_Depth_With_Higher_sum = 0;