【SQL】根據當前ID查詢到其頂層父級的ID


在一個表中,有這樣的一個層級關系,ID為主鍵,PId為父級ID

關系如下圖:

然后呢,現在的需求是,已知某一條記錄的ID,求出它頂層父級的ID,也就是我們所謂的“尋根”計划。

這類問題解決方法很多,首先我用SQL中的函數來解決,許久不寫,正好練習一下:

 1 --創建函數
 2  CREATE   function  F_FindPIdByID
 3 (  
 4    @ID varchar(15) --參數
 5 )
 6 returns varchar(500)
 7 as
 8 begin
 9 
10 declare @PId varchar(15) --變量父級ID,當前ID的PID
11 declare @Place varchar(500)    --變量Place,最終返回結果
12 set  @Place = '0' 
13 begin
14 --首先根據傳入的ID獲取其父ID,PID
15  SELECT    @PId = PId  FROM T_Recursion 
16     where  ID = @ID   
17 end
18 
19  if (@PId<> '0')--如果不是根節點
20     begin            
21         -- 再將@PID 作為參數@ID傳入函數進行自調用        
22         set @Place =dbo.F_FindPIdByID(@PId);        
23     end
24  else
25     begin 
26         --滿足PId=0這個條件,則把當前傳入函數中的ID賦值並返回,即當前的PId就是最終要獲取到的ID           
27         set @Place =@ID
28     end
29 return  @Place
30 end
31 go

函數創建好了(有點遞歸的味道)

 

下面給定參數,然后執行函數,看看結果

1 --測試A
2 select dbo.F_FindPIdByID(1111) as 'ID'
3 
4 --測試B
5 select dbo.F_FindPIdByID(21) as 'ID'
6 
7 --測試C
8 select dbo.F_FindPIdByID(31) as 'ID'

測試的結果

 
        

大功告成。

接下來,我們試試另一個方法。直接寫查詢語句來實現,這里要用到[ WITH AS ]。

什么是WITH AS?

1、WITH AS短語,也叫做子查詢部分(subquery factoring),可以定義一個SQL片斷,該SQL片斷會被整個SQL語句用到。可以使SQL語句的可讀性更高,也可以在UNION ALL的不同部分,作為提供數據的部分。

2、對於UNION ALL,使用WITH AS定義了一個UNION ALL語句,當該片斷被調用2次以上,優化器會自動將該WITH AS短語所獲取的數據放入一個Temp表中。而提示meterialize則是強制將WITH AS短語的數據放入一個全局臨時表中。很多查詢通過該方式都可以提高速度。

搞清楚什么是 with as,我們就來用一下,核心思想是ID作為PId條件找到上級ID

1 with Tree  AS
2 (
3     SELECT * FROM T_Recursion WHERE ID = 1111
4     UNION ALL
5     SELECT a.* FROM Tree , T_Recursion as a WHERE Tree.PId = a.ID
6 )
7 SELECT * FROM Tree order by ID ASC;

執行一下,我們發現結果是所有與之相關的記錄:

,目的達到,完結撒花...

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM