sql >> データベース >  >> RDS >> Sqlserver

SQLで最上位の親を見つける

    再帰CTEを使用して、次のことを実現できます。

    DECLARE @childID INT 
    SET @childID  = 1 --chield to search
    
    ;WITH RCTE AS
    (
        SELECT *, 1 AS Lvl FROM RelationHierarchy 
        WHERE ChildID = @childID
    
        UNION ALL
    
        SELECT rh.*, Lvl+1 AS Lvl FROM dbo.RelationHierarchy rh
        INNER JOIN RCTE rc ON rh.CHildId = rc.ParentId
    )
    SELECT TOP 1 id, Name
    FROM RCTE r
    inner JOIN dbo.Person p ON p.id = r.ParentId
    ORDER BY lvl DESC
    

    SQLFiddleデモ

    編集 -すべての子供のためのトップレベルの親の更新されたリクエストの場合:

    ;WITH RCTE AS
    (
        SELECT  ParentId, ChildId, 1 AS Lvl FROM RelationHierarchy 
    
        UNION ALL
    
        SELECT rh.ParentId, rc.ChildId, Lvl+1 AS Lvl 
        FROM dbo.RelationHierarchy rh
        INNER JOIN RCTE rc ON rh.ChildId = rc.ParentId
    )
    ,CTE_RN AS 
    (
        SELECT *, ROW_NUMBER() OVER (PARTITION BY r.ChildID ORDER BY r.Lvl DESC) RN
        FROM RCTE r
    
    )
    SELECT r.ChildId, pc.Name AS ChildName, r.ParentId, pp.Name AS ParentName
    FROM CTE_RN r
    INNER JOIN dbo.Person pp ON pp.id = r.ParentId
    INNER JOIN dbo.Person pc ON pc.id = r.ChildId
    WHERE RN =1
    

    SQLFiddleデモ

    編集2 -すべての人に最後にJOINSを少し変更させるには:

    SELECT pc.Id AS ChildID, pc.Name AS ChildName, r.ParentId, pp.Name AS ParentName
    FROM dbo.Person pc 
    LEFT JOIN CTE_RN r ON pc.id = r.CHildId AND  RN =1
    LEFT JOIN dbo.Person pp ON pp.id = r.ParentId
    

    SQLFiddle DEMo



    1. postgresフロントエンドでタブを指定する方法COPY

    2. SQL Server Express Editionでストアドプロシージャを毎日実行するにはどうすればよいですか?

    3. MySQLで大文字を含む行を見つける3つの方法

    4. データセットビューのテーブルで時間を節約するための25のMicrosoftAccessショートカット