Frage

Ich versuche einen Weg zu finden, um alle Vorfahren eines bestimmten Knotens mithierarchyid zu bekommen. Jede Lösung, die ich mit Hierarchie gesehen habe, scheint entweder eine CTE oder eine Variable zu verwenden. Gibt es eine Möglichkeit, dies mit einer einzelnen Auswahlanweisung zu tun?

Um die Dinge einfacher zu machen:

CREATE TABLE Employee
(
    EmpId INT PRIMARY KEY IDENTITY,
    EmpName VARCHAR(100) NOT NULL,
    Position HierarchyID NOT NULL
)

INSERT INTO Employee (EmpName, Position)
VALUES ('CEO', '/'),
    ('COO', '/1/'),
    ('CIO', '/2/'),
    ('CFO', '/3/'),
    ('VP Financing', '/3/1/'),
    ('Accounts Receivable', '/3/1/1/'),
    ('Accountant 1', '/3/1/1/1/'),
    ('Accountant 2', '/3/1/1/2/'),
    ('Accountant 3', '/3/1/1/3/'),
    ('Accounts Payable', '/3/1/2/'),
    ('Accountant 4', '/3/1/2/1/'),
    ('Accountant 5', '/3/1/2/2/'),
    ('DBA', '/2/1/'),
    ('VP of Operations', '/1/1/')
War es hilfreich?

Lösung

Um "alle übergeordneten Knoten eines bestimmten Knotens" zu erhalten:

select *, position.GetAncestor(1), position.GetAncestor(1).ToString()
from employee
where position=hierarchyid::Parse('/3/1/')

EmpId  EmpName       Position  (No column name)  (No column name)
5      VP Financing  0x7AC0    0x78              /3/

Aber es wird immer nur eine aufgrund der Natur der Hierarchien geben.

Wenn Sie wirklich alle sofort werden wollen Kinder Knoten eines bestimmten Knotens:

select * 
from employee 
where position.IsDescendantOf(hierarchyid::Parse('/3/1/'))=1
      and position.GetLevel()=hierarchyid::Parse('/3/1/').GetLevel()+1

EmpId  EmpName              Position
6      Accounts Receivable  0x7AD6
10     Accounts Payable     0x7ADA

-- BEARBEITEN

Ich sehe, dass Sie alle Vorfahrenknoten wollen. Vielleicht versuchen Sie einen solchen Ansatz:

select * 
from employee
where hierarchyid::Parse('/3/1/2/1/').IsDescendantOf(Position) = 1

oder

select * from employee
where ( select position 
        from employee 
        where empname='Accountant 4' ).IsDescendantOf(Position) = 1

Hier ist eine CTE -Vergleichsmethode:

with w as ( select * from employee where empname='Accountant 4'
            union all
            select e.*
            from employee e join w on(w.position.GetAncestor(1)=e.Position) )
select * from w;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit dba.stackexchange
scroll top