我在工作期间遇到了一个查询,无法弄清楚它是如何工作的。查询的作用是查找今天是其父母的人的所有父母。
现在这里的技巧是每个父子关系都有一个有效的持续时间。
以此数据集为参考:
从 01-01-2012 到 02-02-2015 GrandParent 是父亲的父母
从 01-01-2012 到 02-02-2011 父亲是孩子的父母
孩子只是最底层的人
NewFather 是 Child 从 01-01-2012 到 02-02-2014 的父母
现在,今天对孩子有效的父母名单应该只包括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;
哪里personID
是绑定变量
此查询不起作用,因为 where 子句的行为是它首先获取所有记录,然后检查非连接条件(检查开始日期和结束日期)。这导致它给出的父母名单NewFather, GrandParent
是完全错误的!
因此,查询更改为以下内容:
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 = (SELECT per_id
FROM ci_acct_per
WHERE per_id = :personID
AND pp.start_dt <= SYSDATE
AND ( pp.end_dt IS NULL
OR pp.end_dt >= SYSDATE ))
CONNECT BY NOCYCLE PRIOR per_id1 = per_id2;
现在我不明白的是:
start with 子句中的 where 条件如何以这种方式影响查询的行为?
我不喜欢这个查询的另一件事是它使用了一个完全不相关的表,该表名为ci_acct_per
,其中per_id
每个人在ci_per_per
.
我们能做得更好吗?是否有更清洁的方法可用于修复原始查询?
更新
此查询仅在层次结构中较高且在我们正在寻找孩子时才有效。但是,此查询从不寻找孩子,也不应该这样做。