Sql oracle中的递归查询
我在oracle中有两个表用于获取软件版本Sql oracle中的递归查询,sql,oracle,hierarchical-data,recursive-query,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
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)
提前感谢测试数据
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)
质疑
对我来说,理解逻辑仍然很困难。在这个查询中,我尝试从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个嵌套查询组成,从最深的一个查询解释
下面是一个使用递归分解子查询的解决方案。它使用bind变量inputversion作为输入起点的机制(例如20.0.0)
很难理解表OptimumVersion如何影响期望的输出。在您的输出中,它只是以某种顺序按所需版本打印所有行。你能给我们举一个更复杂的例子吗?让我们假设i/p为20.0.0,我们应该检查所需的版本表MAJURE=20、MAJURE=0和maintenance=0。如果有任何需要的版本,请获取该版本。像wise一样,我们应该检查最佳版本表MARGIN=20、MARGIN=0和MAINTERNATION=0,并获得最佳版本。对于每个请求或选择,我们应遵循上述步骤。谢谢。让我来处理这个问题,以获取所需的数据
distinct
不是一个函数
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;
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
;