Database “分层查询”;以“开始”;where子句行为

Database “分层查询”;以“开始”;where子句行为,database,oracle,hierarchy,connect-by,Database,Oracle,Hierarchy,Connect By,我在工作中遇到了一个问题,无法弄清楚它到底是如何工作的。查询所做的是查找一个人的所有父母,而这个人现在是他的父母 这里的技巧是每个父子关系都有一个有效的持续时间 将此数据集作为参考: 从2012年1月1日到2015年2月2日,祖父母是父亲的父母 2012年1月1日至2011年2月2日,父亲是孩子的父母 孩子只是最低级的人 2012年1月1日至2014年2月2日,新父亲是孩子的父母 现在,现在对孩子有效的父母名单应该只包括NewFather 为了获取列表,我们之前使用了以下SQL: SELECT

我在工作中遇到了一个问题,无法弄清楚它到底是如何工作的。查询所做的是查找一个人的所有父母,而这个人现在是他的父母

这里的技巧是每个父子关系都有一个有效的持续时间

将此数据集作为参考:

从2012年1月1日到2015年2月2日,祖父母是父亲的父母

2012年1月1日至2011年2月2日,父亲是孩子的父母

孩子只是最低级的人

2012年1月1日至2014年2月2日,新父亲是孩子的父母

现在,现在对孩子有效的父母名单应该只包括
NewFather

为了获取列表,我们之前使用了以下SQL:

SELECT connect_by_root per_id2 AS per_id2,
       per_id1,
       LEVEL                   AS per_level,
       n.entity_name
FROM   ci_per_per pp,
       ci_per_name N
WHERE  N.per_id = per_id1
       AND start_dt <= SYSDATE
       AND ( end_dt IS NULL
              OR end_dt >= SYSDATE )
START WITH per_id2 = :personID
CONNECT BY NOCYCLE PRIOR per_id1 = per_id2;
现在我不明白的是:

start with子句中的where条件如何以这种方式影响查询的行为

关于这个查询,我不喜欢的另一件事是,它使用了一个名为
ci\u acct\u per
的完全不相关的表,对于
ci\u per\u per
中的每个人,该表中只包含一列
per\u id

我们能做得更好吗?是否有更干净的方法来修复原始查询

更新


这个查询只有在层次结构中的位置较高时才起作用,而在我们寻找子对象时则不起作用。但是,此查询从不查找子项,也不应该查找子项。

您可以在connect by子句中使用日期逻辑

SELECT connect_by_root per_id2 AS per_id2,
       per_id1,
       LEVEL                   AS per_level,
       n.entity_name
FROM   ci_per_per pp,
       ci_per_name N
WHERE  N.per_id = per_id1
START WITH per_id2 = :personID AND 
                         SYSDATE BETWEEN start_dt AND NVL(end_dt,SYSDATE)
CONNECT BY NOCYCLE PRIOR per_id1 = per_id2 AND 
                         SYSDATE BETWEEN start_dt AND NVL(end_dt,SYSDATE);

当当前日期没有有效的父母时,这将停止上升。

我不确定我是否正确理解你,但为什么不:

SELECT connect_by_root per_id2 AS per_id2,
       pp.per_id1,
       LEVEL                   AS per_level,
       n.entity_name
FROM   (select * 
        from ci_per_per
       where start_dt <= SYSDATE
       AND ( end_dt IS NULL
              OR end_dt >= SYSDATE )) pp join
       ci_per_name N on N.per_id = pp.per_id1         
START WITH per_id2 = 1
CONNECT BY NOCYCLE PRIOR pp.per_id1 = pp.per_id2;

事实上,我需要查询中使用的所有列,只是错误只影响您建议的列。您的方法仅适用于1级层次结构,而不适用于多级层次结构!!!这就是我认为你想要的。我被你的陈述弄糊涂了:“这个查询所做的是寻找一个人今天的父母的所有父母。”,“现在对孩子有效的父母名单应该只包括新父亲”,“这导致它给出了父母作为新父亲、祖父母的名单,这是完全错误的!”-不知怎么的,我以为祖父母是新爸爸的父母,对不起,别担心,兄弟!只需适当地更改您的答案或删除您的答案就可以了:)@user1395,mmmm。。。这就解释了一切。。。OP中的wierd查询也不起作用!现在,这是有道理的。我记得我建议了一些类似于写新查询的人的东西,然后他提出了那个奇怪的查询,但我忘记了所有这些!然而,我仍然想知道他的查询是如何工作的!我不知道。。。这是更奇怪的-这也工作哈哈哈!我猜主sql的where子句实现有缺陷!或者按照上面的答案等待,这可能是
START WITH
的实现方式!
SELECT connect_by_root per_id2 AS per_id2,
       pp.per_id1,
       LEVEL                   AS per_level,
       n.entity_name
FROM   (select * 
        from ci_per_per
       where start_dt <= SYSDATE
       AND ( end_dt IS NULL
              OR end_dt >= SYSDATE )) pp join
       ci_per_name N on N.per_id = pp.per_id1         
START WITH per_id2 = 1
CONNECT BY NOCYCLE PRIOR pp.per_id1 = pp.per_id2;
select * from (
SELECT connect_by_root per_id1 AS per_id2,
       per_id1,
       LEVEL                   AS per_level,
       n.entity_name
FROM   ci_per_per pp,
       ci_per_name N
WHERE  N.per_id = per_id1       
START WITH per_id1 = 1
CONNECT BY NOCYCLE PRIOR per_id1 = per_id2 AND start_dt <= SYSDATE
       AND ( end_dt IS NULL
              OR end_dt >= SYSDATE ))
where per_id1 <> per_id2;