Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

SQL Server CTE - Намиране на най-горния parentID за всяко дете?

Не можете ли да направите нещо подобно?

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

Поставете CROSS APPLY след дефиницията на CTE - в един SQL оператор, който препраща обратно към CTE. Това няма ли да свърши работа??

ИЛИ: - обърнете логиката си - направете CTE "отгоре надолу", който първо избира възлите от най-високо ниво и след това итерира през йерархията. По този начин можете лесно да определите "бащата от най-високо ниво" в първата част на рекурсивния CTE - нещо подобно:

;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

Това ще ви даде възли нещо подобно (въз основа на вашите примерни данни, леко разширени):

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

Сега, ако изберете конкретен дъщерен възел от този CTE изход, винаги ще получавате цялата необходима информация - включително „нивото“ на дъщерния възел и неговия родителски възел от най-високо ниво.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Използване на динамично наименувана таблица в задача за поток от данни на SSIS

  2. Сложна SQL заявка - намиране на елементи, съответстващи на множество различни външни ключове

  3. Намерете първичен ключ от една таблица в списък, разделен със запетая

  4. SqlParameter не позволява име на таблица - други опции без атака на sql инжекция?

  5. Създайте персонализирано съобщение за грешка в ограниченията за проверка в SQL SERVER 2008