sql >> Database teknologi >  >> RDS >> Sqlserver

SQL Server CTE - Find det øverste forældre-ID for hvert barn-ID?

Kan du ikke gøre sådan noget?

;WITH cte AS (....)
SELECT
    * 
FROM 
    cte
CROSS APPLY 
    dbo.myTable tbl ON cte.XXX = tbl.XXX
 

Indsæt CROSS APPLY efter CTE-definitionen - ind i den ene SQL-sætning, der refererer tilbage til CTE. Ville det ikke virke?

ELLER: - vend rundt på din logik - lav en "top-down" CTE, der vælger top-niveau noderne først, og derefter itererer gennem hierarkiet. På denne måde kan du nemt bestemme "top-level far" i den første del af den rekursive CTE - noget som dette:

;WITH ChildParent AS ( SELECT ID, ParentID = ISNULL(ParentID, -1), SomeName, PLevel = 1, -- defines level, 1 = TOP, 2 = immediate child nodes etc. TopLevelFather = ID -- define "top-level" parent node FROM dbo.[Agent_Agents] WHERE ParentID IS NULL UNION ALL SELECT a.ID, ParentID = ISNULL(a.ParentID, -1), a.SomeName, PLevel = cp.PLevel + 1, cp.TopLevelFather -- keep selecting the same value for all child nodes FROM dbo.[Agent_Agents] a INNER JOIN ChildParent cp ON r.ParentID = cp.ID ) SELECT ID, ParentID, SomeName, PLevel, TopLevelFather FROM ChildParent

Dette ville give dig noder noget som dette (baseret på dine eksempeldata, lidt udvidet):

ID ParentID SomeName PLevel TopLevelFather 20 -1 Top#20 1 20 4 -1 TOP#4 1 4 8 -1 TOP#8 1 8 7 8 ChildID = 7 2 8 3 7 ChildID = 3 3 8 2 4 ChildID = 2 2 4 9 20 ChildID = 9 2 20 5 9 ChildID = 5 3 20 1 5 ChildID = 1 4 20

Hvis du nu vælger en bestemt underordnet node fra denne CTE-udgang, får du altid alle de oplysninger, du har brug for - inklusive barnets "niveau" og dets overordnede node på øverste niveau.



  1. Sådan installeres MySQL Workbench på Windows

  2. Henter rækkerne ved hjælp af joinforespørgsel

  3. SQL Injection beskyttelse med kun str_replace

  4. Konvertering af Long til Varchar2