在oracle中递归查询

时间:2016-07-03 06:02:37

标签: sql oracle hierarchical-data recursive-query

我在oracle中有两个用于获取软件版本的表

RequiredVersion Table
major minor maintenance requiredversion
20      0      0         20.0.1
20      0      1         20.0.3
20      0      3          null
20      0      4          null
20      0      2         20.0.5
20      0      5          null
20      0      6          null

OptimumVersion Table
major minor maintenance optimumver
20      0       0          20.0.2
20      0       2          20.0.6
20      0       1          20.0.4 

用户将发送此版本的输入20.0.0我将拆分并与两个表中的主要次要和维护进行比较。如何获得所有依赖项,即所需版本和最佳版本

I/P       20.0.0
O/p       20.0.1
          20.0.2
          20.0.3
          20.0.4
          20.0.5
          20.0.6

我得到的每个版本可能有也可能没有要求和最佳版本。我尝试了很多使用查询,但没有得到我们如何调用循环。请帮我解决这个问题。

Structure :                20.0.0 
                         /        \ 
        (reqver)   20.0.1          20.0.2 (optimumvers) 
                  /     \          /     \ 
            20.0.3     20.0.4    20.0.5   20.0.6
           (reqver)   (optver)  (req)      (opt) 

提前致谢

3 个答案:

答案 0 :(得分:1)

示例数据

-- Data preparation
CREATE TABLE REQUIRED_VERSION
  (
    MAJOR           NUMBER(3),
    MINOR           NUMBER(3),
    MAINTENANCE     NUMBER(3),
    REQUIREDVERSION VARCHAR2(11)
  );

CREATE TABLE OPTIMUM_VERSION
  (
    MAJOR          NUMBER(3),
    MINOR          NUMBER(3),
    MAINTENANCE    NUMBER(3),
    OPTIMUMVERSION VARCHAR2(11)
  );

-- Data
Insert into OPTIMUM_VERSION (MAJOR,MINOR,MAINTENANCE,OPTIMUMVERSION) values ('20','0','0','20.0.2');
Insert into OPTIMUM_VERSION (MAJOR,MINOR,MAINTENANCE,OPTIMUMVERSION) values ('20','0','2','20.0.6');
Insert into OPTIMUM_VERSION (MAJOR,MINOR,MAINTENANCE,OPTIMUMVERSION) values ('20','0','1','20.0.4');

Insert into REQUIRED_VERSION (MAJOR,MINOR,MAINTENANCE,REQUIREDVERSION) values ('20','0','0','20.0.1');
Insert into REQUIRED_VERSION (MAJOR,MINOR,MAINTENANCE,REQUIREDVERSION) values ('20','0','1','20.0.3');
Insert into REQUIRED_VERSION (MAJOR,MINOR,MAINTENANCE,REQUIREDVERSION) values ('20','0','3',null);
Insert into REQUIRED_VERSION (MAJOR,MINOR,MAINTENANCE,REQUIREDVERSION) values ('20','0','4',null);
Insert into REQUIRED_VERSION (MAJOR,MINOR,MAINTENANCE,REQUIREDVERSION) values ('20','0','2','20.0.5');
Insert into REQUIRED_VERSION (MAJOR,MINOR,MAINTENANCE,REQUIREDVERSION) values ('20','0','5',null);
Insert into REQUIRED_VERSION (MAJOR,MINOR,MAINTENANCE,REQUIREDVERSION) values ('20','0','6',null);

<强>查询

SELECT DISTINCT DEPENDENCY
FROM (
  SELECT VERSION,DEPENDENCY
  FROM (
    SELECT MAJOR||'.'||MINOR||'.'||MAINTENANCE AS VERSION, REQUIREDVERSION AS DEPENDENCY FROM REQUIRED_VERSION
    UNION
    SELECT MAJOR||'.'||MINOR||'.'||MAINTENANCE AS VERSION, OPTIMUMVERSION AS DEPENDENCY FROM OPTIMUM_VERSION
  )
  START WITH VERSION = '20.0.0' -- Put your version number here
  CONNECT BY PRIOR DEPENDENCY = VERSION AND DEPENDENCY IS NOT NULL
)
ORDER BY DEPENDENCY ASC;

解决方案由3个嵌套查询组成,从最深层次的解释中解释。

  1. 使用点连接主要版本,次要版本,维护版本,以便像处理所需版本(即varchar2)一样处理此连接。将两个表合并为一个(显然,依赖表分为两部分)
  2. 分层查询 - 听起来像什么。对于每个具有依赖关系的行都会生成“root”并加载它的依赖关系(如果有的话)
  3. 过滤结果只显示一次依赖关系(如果是两个版本依赖于其他依赖关系)。订单按升序排列。

答案 1 :(得分:0)

测试数据

WITH RequiredVersion(major, minor, maintenance, requiredversion) AS(
SELECT 20,0,0,'20.0.1' FROM dual
  UNION all
SELECT 20,0,1,'20.0.3' FROM dual
  UNION all
SELECT 20,0,3,null FROM dual
  UNION all
SELECT 20,0,4,null FROM dual
  UNION all
SELECT 20,0,2,'20.0.5' FROM dual
  UNION all
SELECT 20,0,5,null FROM dual
  UNION all
SELECT 20,0,6,null FROM dual),
OptimumVersion(major, minor, maintenance, optimumver) AS(
SELECT 20,0,0,'20.0.2' FROM dual
  UNION all
SELECT 20,0,2,'20.0.6' FROM dual
  UNION all
SELECT 20,0,1,'20.0.4' FROM dual)

查询

SELECT DISTINCT major, minor, maintenance FROM 
 (SELECT * FROM RequiredVersion UNION ALL SELECT * FROM OptimumVersion)
    CONNECT BY PRIOR requiredversion = major || '.' || minor || '.' || maintenance
    START WITH major = 20 and minor= 0 and maintenance = 0
  ORDER BY major, minor, maintenance

对我来说,理解逻辑仍然很困难。在此查询中,我尝试使用RequiredVersion和OptimumVersion中的联合数据,并构建层次结构以删除重复的行。

答案 2 :(得分:0)

这是一个使用递归因式子查询的解决方案。它使用bind变量:inputversion作为输入起点的机制(例如20.0.0)

with 
     dep_version (version, dependentversion) as (
       select major || '.' || minor || '.' || maintenance, requiredversion
       from   required_version
       union all
       select major || '.' || minor || '.' || maintenance, optimumversion
       from optimum_version
     ),
     rec (dependentversion) as (
       select :inputversion from dual
       union all
       select d.dependentversion
       from   rec r inner join dep_version d 
                          on   r.dependentversion = d.version
       where  d.dependentversion is not null
     ) 
select dependentversion
from   rec
where  dependentversion != :inputversion
;