我在工作中遇到了一個查詢,無法弄清楚它的工作原理。查詢所做的就是查找所有父母,以便今天是其父母的人員。分層查詢使用where子句行爲「START WITH」
現在這裏的訣竅是每個父母子女關係都有一個有效的持續時間。
取本數據設定爲基準:
祖父母是從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;
現在我不明白的是:
WHERE條件在開始與子句如何影響行爲以這種方式查詢?
,我不喜歡這個查詢的另一件事是,它使用一個名爲ci_acct_per
它只是有它per_id
中的每個人ci_per_per
列一個完全不相關的表。
我們可以做得更好嗎?清理方法是否可用於修復原始查詢?
UPDATE
這個查詢只能當行駛在更高的層次,而不是如果我們正在尋找孩子。但是,這個查詢從不查找孩子,也不應該這樣做。
請幫助傢伙! – MozenRath 2013-02-14 08:57:21