0

それ自体を参照するテーブルがあります。

ユーザーテーブル:id, username, manageridおよびmanageridリンク先id

今、私は直属のマネージャー、直属のマネージャーのマネージャーなどを含むすべてのマネージャーを取得したい...問題は、unstop recursive sql を持ちたくないということです。

そのため、ID が既にリストにあるかどうかを確認したいので、もう含めません。

そのための私の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 guy のすべてのマネージャーを見つけたいということです。結果は次のようになります: admin, a, b.

ManagerID は NULL を許可せず、一部のユーザーは直属のマネージャーを持たないため、一部のユーザーは自分のマネージャー (管理者など) になることができます。

共通テーブル式では、無限再帰につながる可能性があります。そのため、IDを2回含めないようにすることで、その状況を回避しようとしています。たとえば、1 回目の反復では既に id : 1 があるため、2 回目以降の反復では 1 は許可されません。

また、現在のアプローチが良いかどうか、および他の解決策があるかどうかも尋ねたいと思いますか? 深い階層を持つ大きなデータベースがある場合、それを保持するために大きな varchar を初期化する必要があり、メモリを消費しますよね?

4

1 に答える 1

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;

ただし、あなたが何を達成しようとしているのかはまだよくわかりません。結果セットで返すべきものと返すべきでないもののサンプル データをいくつか示してもらえますか?

于 2010-05-01T17:14:00.343 に答える