SQL應用之查詢根節點

2021-07-22 18:48:21 字數 1395 閱讀 4512

mssql提供了cte遞迴取資料的方法,但是沒有直接提供乙個給定任意節點查詢其根節點的方法(也是ms sql 2008之後的版本有我不知道)。

此外,如果資料庫提供的資料出現死循時,如果沒有相應的檢測機制,必然導致資料庫伺服器資源耗盡。因此查詢根節點的sql片斷(或儲存過程)也是相當有用的。

declare @table table(id int,pid int,name varchar(20))

insert

into @table

values(1,null,'a'),(2,8,'b'),(3,1,'b'),(4,2,'b'),(5,2,'b'),

(6,3,'b'),(7,4,'b'),(8,7,'b'),(9,8,'b')

-- 迴圈中開始2 -> 8 -> 7 -> 4 -> 2

-- 迴圈外開始9 -> 8 -> 7 -> 4 -> 2 -> 8 ->...

declare @paramid int = 7,@rootpid int = null,@id int,@tmpid int,

@count

int = (select

count(*) from @table),@i int = 0

set @id = @paramid

while 1=1

begin

set @i += 1

select @tmpid = pid from @table

where id = @id -- 多值不合法,但只取乙個值

if (@rootpid is

null

and @tmpid is

null)

or (@rootpid is

notnull

and @tmpid = @rootpid)

or @id = @tmpid /*自身引用死迴圈*/

or @tmpid = @paramid /*迴圈中死迴圈*/

or @i > @count /*各種情況的死迴圈*/

break

set @id = @tmpid

endselect @id

-- 警告: 聚合或其他 set 操作消除了 null 值。

-- (1)(select pid from @table

where id = @id) is

notnull

-- (2)set @id int = (select id from @table)

-- 執行時錯誤:子查詢返回的值不止乙個。當子查詢跟隨在 =、!=、<、<=、>、>= 之後,或子查詢用作表示式時,這種情況是不允許的。

注:以上sql目的在於查詢根節點,防止死迴圈,對出現「迴圈資料」時返回結果未作嚴格處理,根據需要稍作修改即可。

SQL查詢根節點

地點 廣東深圳 create table tb id varchar 3 pid varchar 3 name varchar 10 insert into tb values 001 null 廣東省 insert into tb values 002 001 廣州市 insert into tb...

SQLite應用之路 SQL查詢優化

temp1 2499條資料 temp6 969596條資料 注意時間單位ms和s 其中temp1和temp2已經給eid加上索引 外表大於子表的時候,使用in 外表小於字表的時候,使用exists select from temp1 where eid in select eid from temp...

oracle 樹狀查詢,查詢根節點

1 第一種方法 sql select to number substr path,2,instr path,2 2 root id,id 2 from 3 4 select sys connect by path id,path,id 5 from test 6 where rownum 10 7 ...