[英]SQL recursive records: How can I collapse to 'one level only'?
我有一個帶有項目ID和'inherit id'的記錄,即當前項目繼承的項目。 繼承級別未知。
我現在需要將其折疊為:'從最頂層繼承'
例如:
1006 <- 1005 <- 1002 <- 999
prj_id / inherit_id
999 / 1002
1002 / 1005
1005 / 1006
應該崩潰到
1006 <- 1005
1006 <- 1002
1006 <- 999
prj_id / inherit_id
999 / 1006
1002 / 1006
1005 / 1006
這可以在沒有循環的SQL語句中完成嗎? 創建臨時表很好。 它適用於FireBird,SQL Server,Oracle 9+(即3套語句都可以)
我只有這么遠:
從自身再次繼承的記錄繼承的記錄:
select tt_prj_id,tt_name,tt_inherit_id from tt_prj a
where a.tt_inherit_id in
(select tt_prj_id from tt_prj b
where b.tt_inherit_id is not null
and b.tt_inherit_id > 0)
誰可以幫我進一步?
像下面這樣的東西應該讓你開始(這不是最終的解決方案!):
with recursive project_tree as (
select tt_prj_id, cast(tt_prj_id as varchar(500))||'/' as id_path, tt_prj_id as root_id
from tt_prj
where tt_inherit_id = 0
union all
select c.tt_prj_id, id_path || cast(c.tt_prj_id as varchar(100)) ||'/', null
from tt_prj c
join project_tree p on c.tt_inherit_id = p.tt_prj_id
)
select *
from project_tree;
這適用於Firebird 2.5(可能也適用於2.1,但我現在手頭沒有)
當你刪除關鍵字recursive
時它應該與SQL Server一起工作(這是ANSI標准所要求的,但是從那時起微軟關心那個......)你需要替換標准字符串連接||
使用+
運算符。
Oracle在11.2之前只支持遞歸CTE。 在以前的版本中,您需要使用CONNECT BY
重寫它,這可能是這樣的:
select tt_prj_id, tt_inherit_id, sys_connect_by_path(tt_prj_id, '/')
from tt_prj
start with tt_inherit_id = 0
connect by prior tt_prj_id = tt_inherit_id;
對transitive closure tables
或nested sets
進行搜索。 它們的結構使得有效查詢關系數據成為可能,但是它需要對插入/更新/刪除進行更多維護,並且關閉表將需要存儲額外的記錄(權衡空間以提高效率)。
用戶a_horse_with_no_name是正確的。 可以使用遞歸CTE執行此操作。 查看此鏈接以獲取更多信息。
http://blog.sqlauthority.com/2008/07/28/sql-server-simple-example-of-recursive-cte/
再一次,Pinal Dave ftw。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.