4

以下のコードでは、SQL Server 2005 で再帰的な CTE (Common Table Expression) を使用して、基本的な階層構造の最上位レベルの親を見つけようとしています。この階層のルールは、すべての CustID に ParentID があり、CustID に親がない場合、ParentID = CustID であり、それが最上位レベルです。

DECLARE @LookupID int

--Our test value
SET @LookupID = 1

WITH cteLevelOne (ParentID, CustID) AS
(
        SELECT   a.ParentID, a.CustID
        FROM     tblCustomer AS a
        WHERE    a.CustID = @LookupID
    UNION ALL
        SELECT   a.ParentID, a.CustID
        FROM     tblCustomer AS a
        INNER JOIN cteLevelOne AS c ON a.CustID = c.ParentID
        WHERE c.CustID <> a.CustomerID
)

したがって、tblCustomer が次のようになっている場合:

ParentID    CustID
5            5
1            8
5            4
4            1

上記のコードから得られる結果は次のとおりです。

ParentID    CustID
4            1
5            4
5            5

私が欲しいのは、その結果の最後の行だけです:

ParentID    CustID
5            5

CTE で生成された最後のレコード (最高レベルの CustID) を返すにはどうすればよいですか?

また、このテーブルには関連のない CustID 階層が複数あるため、単に SELECT * FROM tblCustomer WHERE ParentID = CustID を実行することはできません。ID 番号は階層のどこにあるかに関連していないため、ParentID または CustID で注文することはできません。

4

3 に答える 3

3

再帰の深さを最大にしたい場合は、このようなことはできませんか?次に、実際にCTEにクエリを実行するときに、max(Depth)の行を探しますか?そのようです:

DECLARE @LookupID int

--Our test value
SET @LookupID = 1;

WITH cteLevelOne (ParentID, CustID, Depth) AS
(
        SELECT   a.ParentID, a.CustID, 1
        FROM     tblCustomer AS a
        WHERE    a.CustID = @LookupID
    UNION ALL
        SELECT   a.ParentID, a.CustID, c.Depth + 1
        FROM     tblCustomer AS a
        INNER JOIN cteLevelOne AS c ON a.CustID = c.ParentID 
        WHERE c.CustID <> a.CustID
)
select * from CTELevelone where Depth = (select max(Depth) from CTELevelone)

または、trevorが示唆することを適応させて、これを同じCTEで使用することができます。

select top 1 * from CTELevelone order by Depth desc

あなたが説明した場合、CustomerIDが必ずしも注文したいものであるとは思いませんが、質問についても完全には明確ではありませんでした。

于 2008-08-30T01:42:45.613 に答える
1

問題を完全に理解しているのかどうかはわかりませんが、ハックして切り詰めるだけで、次のことを試すことができます。

SELECT TOP 1 FROM cteLevelOne ORDER BY CustID DESC

これは、CustIDも例のように順序付けられており、GUIDのようなものではないことを前提としています。

于 2008-08-29T22:40:16.427 に答える
0

まず、親子のいずれかが同じである場合、cte は終了しません。これは再帰的な CTE であるため、終了する必要があります。Parent と cust id が同じであるため、ループは終了しません。

メッセージ 530、レベル 16、状態 1、行 15 ステートメントは終了しました。ステートメントが完了する前に、最大再帰回数 100 を使い果たしました。

于 2014-07-11T07:06:02.143 に答える