oracle递归查询

Recursively query in oracle

我在 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

我得到的每个版本可能有也可能没有必需的和最佳的版本。我尝试了很多使用查询但没有得到我们如何调用 loop.Please 帮助我解决这个问题。

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) 

提前致谢

测试数据

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 的数据并构建层次结构以删除重复行。

示例数据

-- 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)相同的方式处理此连接。将两个 table 合并为一个(这显然是 table 的依赖项被你分成了两部分)
  2. 分层查询 - 就像它听起来的那样。对于具有依赖关系的每一行都会创建一个 "root" 并加载它的依赖关系(如果有的话)
  3. 过滤结果以仅显示每个依赖项一次(以防万一,它们是两个依赖于另一个的版本)。订单结果按升序排列。

这是一个使用递归分解子查询的解决方案。它使用绑定变量 :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
;