Finden Sie alle Vorfahrknoten einer Hierarchie mit einer einzigen SQL -Anweisung?
-
16-10-2019 - |
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/')
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