2010-05-01 75 views
0

我有一個表引用自身。如何使用公用表表達式並在SQL Server中檢查不重複

用戶表:id, username, manageridmanagerid鏈接回id

現在,我想所有的管理人員,包括直接管理,直接管理的經理,等等等等......問題是,我做的不想有一個不穩定的遞歸sql。

所以,我想檢查一個列表中的id alreay,我不會再包含它了。

這是我爲SQL:

with   
    all_managers (id, username, managerid, idlist) as 
    (
     select u1.id, u1.username, u1.managerid, ' ' 
     from users u1, users u2 
     where u1.id = u2.managerid 
     and u2.id = 6 

     UNION ALL 

     select u.id, u.username, u.managerid, idlist + ' ' + u.id 
     from all_managers a, users u 
     where a.managerid = u.id 
     and charindex(cast(u.id as nvarchar(5)), idlist) != 0 
    ) 
select id, username 
from all_managers; 

的問題是,在這條線:

select u1.id, u1.username, u1.managerid, ' ' 

的SQL Server和我抱怨,我不能把「」作爲初始化IDLIST。 nvarchar(40)不起作用。我不知道如何在像這樣的公共表格表達式中聲明它。通常情況下,在DB2中,我只是把VARCHAR(40)

我的樣本數據:

ID UserName ManagerID 

1 admin  1 
2 a   1 
3 b   1 
4 c   2 

我想要做的是,我想求c傢伙的所有管理人員。結果應該是: admin,a,b。

某些用戶可能是他的經理(如管理員),因爲ManagerID不允許NULL,有些沒有直接經理。

使用公用表表達式,它可能會導致無限遞歸。所以,我也試圖通過不包括id兩次來避免這種情況。例如,在第一次迭代中,我們已經有了id:1,因此,在第二次迭代中以後,絕不應該允許1。

我也想問我目前的方法是否好,還有其他解決方案?因爲如果我有一個深層次的大數據庫,我將不得不初始化一個大的varchar來保存它,並且它會消耗內存,對吧?

回答

2

解決鑄造問題很簡單。您只需要在工會投兩個值相同類型:

With 
    all_managers (id, username, managerid, idlist) as 
    (
     Sselect u1.id, u1.username, u1.managerid 
      , Cast(' ' As varchar(40)) 
     From users As u1 
      Cross Join users As u2 
     Where u1.id = u2.managerid 
      and u2.id = 6 
     Union All 
     Select u.id, u.username, u.managerid 
      , Cast(Coalesce(idlist + ' ','') + Cast(u.id As varchar(10)) As varchar(40)) 
     From all_managers As a 
      Cross Join users As u 
     Where a.managerid = u.id 
      and CharIndex(Cast(u.id as nvarchar(5)), idlist) != 0 
    ) 
Select id, username, idlist 
From all_managers; 

不過,我還是不太清楚你要實現的目標是什麼。你能告訴我們一些什麼樣的數據,應該不應該返回結果集?

相關問題