【问题标题】:Hierarchical queries分层查询
【发布时间】:2016-07-24 10:01:24
【问题描述】:

我创建了某种“依赖项”表,其中包含我们夜间流程的全部依赖项。

表格如下所示:

GRAND_MODEL | WAIT_4_MODEL_NAME
test            test1
test            test2
test            test3
test2           test3
test3           test4
test4           test5

这个表意味着 -> test 需要等待 test1 , test2 , test3 才能完成,但还需要等待 test4 和 test5 ,因为 test3/4等着他们。 test1 不等待任何东西,test2 等待 test3,因此也等待 test4,因此也等待 test5。

所以结果应该是这样的:

FIRST_MODEL | SECOND_MODEL | THIRD_MODEL | FORTH_MODEL | FIFTH_MODEL | SIXTH_MODEL
 test5           test4            test3       test2          test        NULL 
 test5           test4            test3       test           NULL        NULL
 test4           test3            test2       test           NULL        NULL
.................................

我尝试过的:

SELECT distinct prior wait_4_model_name as first_m,
                wait_4_model_name as second_m,
                grand_model as third_m
  from (SELECT distinct grand_model, wait_4_model_name
          FROM DEL_SAGI_FOR_HIERARCHY)
connect by NOCYCLE prior grand_model = wait_4_model_name

但这只会生成层次结构的第一级。

提前致谢。

编辑:请注意,可能存在相反的依赖关系,test 等待 test1 和 test1 等待 test (每个模型都很大,因此可能有一部分模型等待另一个模型的一部分)

【问题讨论】:

  • 你知道层次结构的最大层数吗?
  • 不,但可以说 9 就足够了。 @MT0
  • 关于您的编辑:因此,如果存在相互依赖关系,您将拥有无限序列,不是吗?那么期望的输出是什么?你是否以“CONNECT BY NOCYCLE”的方式打破循环?

标签: sql oracle hierarchy


【解决方案1】:

Oracle 设置:

CREATE TABLE table_name ( GRAND_MODEL, WAIT_4_MODEL_NAME ) AS
SELECT 'test',  'test1' FROM DUAL UNION ALL
SELECT 'test',  'test2' FROM DUAL UNION ALL
SELECT 'test',  'test3' FROM DUAL UNION ALL
SELECT 'test2', 'test3' FROM DUAL UNION ALL
SELECT 'test3', 'test4' FROM DUAL UNION ALL
SELECT 'test4', 'test5' FROM DUAL;

查询:

SELECT REGEXP_SUBSTR( tests, '[^|]+', 1, 1 ) AS first_model,
       REGEXP_SUBSTR( tests, '[^|]+', 1, 2 ) AS second_model,
       REGEXP_SUBSTR( tests, '[^|]+', 1, 3 ) AS third_model,
       REGEXP_SUBSTR( tests, '[^|]+', 1, 4 ) AS fourth_model,
       REGEXP_SUBSTR( tests, '[^|]+', 1, 5 ) AS fifth_model,
       REGEXP_SUBSTR( tests, '[^|]+', 1, 6 ) AS sixth_model,
       REGEXP_SUBSTR( tests, '[^|]+', 1, 7 ) AS seventh_model,
       REGEXP_SUBSTR( tests, '[^|]+', 1, 8 ) AS eighth_model,
       REGEXP_SUBSTR( tests, '[^|]+', 1, 9 ) AS ninth_model
FROM   (
  SELECT SYS_CONNECT_BY_PATH( wait_4_model_name, '|' ) || '|' ||  grand_model AS tests
  FROM  table_name
  CONNECT BY PRIOR grand_model = wait_4_model_name
);

输出:

FIRST_MODEL SECOND_MODEL THIRD_MODEL FOURTH_MODEL FIFTH_MODEL SIXTH_MODEL SEVENTH_MODEL EIGHTH_MODEL NINTH_MODEL
----------- ------------ ----------- ------------ ----------- ----------- ------------- ------------ -----------
test1       test                                                                                                 
test2       test                                                                                                 
test3       test                                                                                                 
test3       test2                                                                                                
test3       test2        test                                                                                    
test4       test3                                                                                                
test4       test3        test                                                                                    
test4       test3        test2                                                                                   
test4       test3        test2       test                                                                        
test5       test4                                                                                                
test5       test4        test3                                                                                   
test5       test4        test3       test                                                                        
test5       test4        test3       test2                                                                       
test5       test4        test3       test2        test                                                           

【讨论】:

  • 经过一些调整后,它就像一个魅力。谢谢。
  • 糟糕的是,此解决方案连接字符串,然后再次拆分它们,还要求数据本身中不出现分隔符。
  • 请在这里查看我对这个问题的以下问题 - stackoverflow.com/questions/38551931/selecting-best-output :)
【解决方案2】:

这里是一个不需要字符串连接和重新拆分的解决方案:

select    a.wait_4_model_name model1,
          a.grand_model       model2,
          b.grand_model       model3,
          c.grand_model       model4,
          d.grand_model       model5,
          e.grand_model       model6
from      DEL_SAGI_FOR_HIERARCHY a
left join DEL_SAGI_FOR_HIERARCHY b ON a.grand_model = b.wait_4_model_name
left join DEL_SAGI_FOR_HIERARCHY c ON b.grand_model = c.wait_4_model_name
left join DEL_SAGI_FOR_HIERARCHY d ON c.grand_model = d.wait_4_model_name
left join DEL_SAGI_FOR_HIERARCHY e ON d.grand_model = e.wait_4_model_name
where     a.wait_4_model_name not in (
              select grand_model from DEL_SAGI_FOR_HIERARCHY)
order by  1, 2, 3, 4, 5, 6

样本数据的输出是:

+--------+--------+--------+--------+--------+--------+
| MODEL1 | MODEL2 | MODEL3 | MODEL4 | MODEL5 | MODEL6 |
+--------+--------+--------+--------+--------+--------+
| test1  | test   |    -   |   -    |   -    |   -    |
| test5  | test4  | test3  | test   |   -    |   -    |
| test5  | test4  | test3  | test2  | test   |   -    |
+--------+--------+--------+--------+--------+--------+

请注意,您的示例数据没有完全没有任何依赖关系的模型实例,即不需要等待另一个模型,也不需要任何模型才能启动。

【讨论】:

  • 感谢您的解决方案,我更喜欢对此进行分层查询,但对于这个想法 +1。我会很感激你看看这个问题:stackoverflow.com/questions/38551931/selecting-best-output
  • 这样做的性能不会很好,因为您需要对层次结构的每一级进行一次表扫描。
  • 仅当您不在这些字段上放置索引时。设置适当的索引后,它不是表扫描。事实上,通过正确设置索引,引擎甚至不必访问表本身,它可以通过索引完成所有操作。
猜你喜欢
  • 1970-01-01
  • 2010-11-24
  • 2020-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多