Oracle - 具有时间成本的分层自下而上查询

时间:2018-02-15 10:51:17

标签: sql oracle oracle11g

我有一个存储组织单位之间关系的表。 这些关系可以在时间上发生变化,因此昨天让一个对象引用父母,以及今天引用另一个父母是完全正常的。 DB中的costraint确保对象只能在给定时间内引用父对象(1:1关系)

现在我想要一个查询,它返回从leaf到root的路径,这是所需时间段内唯一有效的路径。

如果我只有一个关系,我可以运行查询,但如果我插入两个连续关系,我的查询失败,不仅返回我的路径,还返回不属于我的路径的其他组织对象

这些是关系

-- old situation graph
--           1
--       /   |  \
--      11   12  13
--      |    |
--     111  121
--           |
--         1111
--
-- current situation graph
--           1
--       /   |  \
--      11   12  13
--      |    |
--     111  121
--      |
--    1111

只有一个关系我今天和昨天得到这个结果(好)

'CURRENTSITUATION'  KY_UNI_ORG_INF  KY_UNI_ORG_SUP
Current situation   1111            111
Current situation   111              11
Current situation   11                1
Current situation   1                 0

'OLDSITUATION'  KY_UNI_ORG_INF  KY_UNI_ORG_SUP
old situation   111             11
old situation   11               1
old situation   1                0

但有两个关系(取消注释DML句子)我得到了错误的情况

'CURRENTSITUATION'  KY_UNI_ORG_INF  KY_UNI_ORG_SUP
Current situation   1111            111
Current situation   111              11
Current situation   121              12  -- Not in my path
Current situation   12                1  -- Not in my path
Current situation   11                1
Current situation   1                 0
Current situation   1                 0

'OLDSITUATION'  KY_UNI_ORG_INF  KY_UNI_ORG_SUP
old situation   1111            121
old situation   121             12
old situation   111             11  -- Not in my path
old situation   11               1  -- Not in my path
old situation   12               1
old situation   1                0
old situation   1                0

关注一些DDL

CREATE TABLE BORG_APP_UNI_ORG 
(
  KEY_TAB NUMBER(10, 0) NOT NULL 
, KY_UNI_ORG_SUP NUMBER(10, 0) NOT NULL 
, KY_UNI_ORG_INF NUMBER(10, 0) NOT NULL 
, DATA_INIZIO DATE NOT NULL 
, DATA_FINE DATE NOT NULL
) 

DML

INSERT INTO BORG_APP_UNI_ORG VALUES (    1,  0,    1, trunc(sysdate-30), trunc(sysdate+30) );
INSERT INTO BORG_APP_UNI_ORG VALUES (   11,  1,   11, trunc(sysdate-30), trunc(sysdate+30) );
INSERT INTO BORG_APP_UNI_ORG VALUES (   12,  1,   12, trunc(sysdate-30), trunc(sysdate+30) );
INSERT INTO BORG_APP_UNI_ORG VALUES (   13,  1,   13, trunc(sysdate-30), trunc(sysdate+30) );
INSERT INTO BORG_APP_UNI_ORG VALUES (  111, 11,  111, trunc(sysdate-30), trunc(sysdate+30) );
INSERT INTO BORG_APP_UNI_ORG VALUES (  121, 12,  121, trunc(sysdate-30), trunc(sysdate+30) );
-- old relat                                                
-- INSERT INTO BORG_APP_UNI_ORG VALUES ( 1111,121, 1111, trunc(sysdate-30), trunc(sysdate-1) );
-- new relat                                                
INSERT INTO BORG_APP_UNI_ORG VALUES ( 1111, 111, 1111, trunc(sysdate),    trunc(sysdate+30) );

和查询

-- Current
select 'Current situation', r.ky_UNI_ORG_INF, r.ky_UNI_ORG_SUP
from 
    BORG_APP_UNI_ORG r
WHERE 
    trunc(sysdate) BETWEEN r.data_inizio and r.data_fine
CONNECT BY ky_uni_org_inf  = PRIOR ky_uni_org_sup
START WITH ky_uni_org_inf = 1111
order by level
    ;

-- Old
select 'old situation',r.ky_UNI_ORG_INF, r.ky_UNI_ORG_SUP
from 
    BORG_APP_UNI_ORG r
WHERE 
    trunc(sysdate-1) BETWEEN r.data_inizio and r.data_fine
CONNECT BY ky_uni_org_inf  = PRIOR ky_uni_org_sup
START WITH ky_uni_org_inf = 1111
order by level
;    

0 个答案:

没有答案