簡體   English   中英

SQL遞歸記錄:如何折疊到“僅一級”?

[英]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 tablesnested 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM