I'm not sure that I understand you right, but why not:
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;
Update Thanks to @user1395 example:
It's hard to explain how come the strange query works because it doesn't...
What really happens is that the START WITH
clause uses per_id2 which is the "father of" column, so if there are more than one (one isn't relevant to sysdate) you still need not to start with it.
In other words it doesn't start from "child" but from "child" fathers - "father" and "newfather".
So, either use @user1395 suggestion of having date logic in both the connect by
clause to stop when a father isn't relevant, and start with
clause to make only the relevant father available, or remove all unrelevant fathers on the first place (as in my former suggestion) or "start with" the "child" and not its fathers:
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;