2017-04-25 16 views
0

Iは、以下の値を有する:最長ツリーパスのSQLツリー経路構造長

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 | Sum | Tree_path_structure 
1 | 10 | /1/2 
2 | 30 | /1/3/4 
4 | 50 | /1/6 

私は、ツリーパスの構造体の長さに基づいてSQLが最小の合計値を返すようにしたいと思います。

答えて

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; 
+0

ありがとうございます!そして、私が複数のツリーパスを持っていても、以下のデータのようにすべてが最初のレベルで同じツリーを持っているわけではありません。 CREATE TABLE your_table(ID、SUm、Tree_path_structure)DUAL UNION ALL SELECT 2、30、 '/ 1/3/4'からDUAL UNION ALL SELECT 3、40、 '/ 1/3/5 'からDUAL UNIONすべて選択4,50、'/1/6 'からDUAL UNIONすべて選択5,10、'/7/8/9 'からDUAL UNION ALL SELECT 6、15、'/7/10/11 'からDUAL; –

+0

クエリの更新をありがとう。しかし、クエリがツリーとツリーレベルの長さに基づいて最小(合計)値を返す必要がある場合。 –

+0

your_table表を作成する(Idは、SUM、Tree_path_structure) ASはALL \t がALL \t SELECT DUAL結合から\t 2,20 \t、 '/ 1/2' を選択DUAL結合から\t 1,10 \t、 '/ 1' を選択しますALL \t が\t 5,15 \tを選択DUAL UNION FROM \t 3,10 \t、 '/ 1/3' DUAL UNIONからのすべて\t が\t 4,30 \tを選択して、 '/ 1/2/4' \t、 '/ 1/2/5 '\tデュアルユニオンからALL \t SELECT \t 6,40 012 DUAL UNIONからのすべて\t が\t 8,50 \tを選択DUAL UNIONからのすべて\t が\t 7,22 \tを選択DUAL UNION FROM、 '/ 1/3/6'、 '/ 7' \t、 '/ 7/8' ALL \t ALL \t がSELECT DUAL UNION FROM \t 9,60 \t、 '/ 7/8/9' を選択\t 10,19、 '/ 7/8/10' \t DUAL UNION ALL FROM \t \t 11,15を選択、 '/ 7/8/11' \tデュアルユニオンからALL \t SELECT \t 12,13 '/ 7/8/12' \t FROM DUAL; –