仕事中にクエリに出くわしましたが、それがどのように機能するのか正確に理解できませんでした。クエリが行うことは、今日その親である人のすべての親を探すことです。
ここでの秘訣は、各親子関係に有効な期間があることです。
このデータセットを参照してください。
祖父母は2012年1月1日から2015年2月2日まで父の親です
父は2012年1月1日から2011年2月2日まで子の親です
子供はただ最低レベルの人です
NewFatherは、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;
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条件は、このような方法でクエリの動作にどのように影響しますか?
このクエリについて私が嫌うもう1つの点は、という名前の完全に無関係なテーブルを使用していることです。このテーブルには、の各人ci_acct_per
の列が含まれているだけです。per_id
ci_per_per
もっと上手くできますか?元のクエリを修正するためのよりクリーンなアプローチはありますか?
アップデート
このクエリは、階層の上位を移動する場合にのみ機能し、子を探している場合は機能しません。ただし、このクエリは子を検索することはなく、検索することも想定されていません。