I have a Locations table that uses a hierarchyid column to map cities/regions/countries/continents. The table looks like this:
declare @Locations table (
LocationNodeID hierarchyid,
LocationID int,
LocationName varchar(50)
)
insert into @Locations (LocationNodeID, LocationID, LocationName) values
(cast('/0/' as hierarchyid), 1, 'World'),
(cast('/0/1/' as hierarchyid), 2, 'North America'),
(cast('/0/1/1/' as hierarchyid), 3, 'United States'),
(cast('/0/1/1/1/' as hierarchyid), 4, 'California'),
(cast('/0/1/1/1/1/' as hierarchyid), 5, 'Los Angeles'),
(cast('/0/1/1/1/2/' as hierarchyid), 6, 'San Francisco'),
(cast('/0/1/1/2/' as hierarchyid), 7, 'Ohio'),
(cast('/0/1/1/2/1/' as hierarchyid), 8, 'Cleveland'),
(cast('/0/1/1/2/2/' as hierarchyid), 9, 'Toledo');
I have a second table that maps events to the locations. This table flattens the hierarchy and has one record per level (I inherited it this way). So if an event is in Los Angeles, there are 4 records for the event in this table: Los Angeles, California, United States, North America. The same event can also be held in multiple locations.
declare @EventLocations table (
EventID int,
LocationID int
)
insert into @EventLocations (EventID, LocationID) values
(1, 2), -- North America
(1, 3), -- United States
(1, 4), -- California
(1, 5), -- Los Angeles (leaf)
(2, 2), -- North America
(2, 3), -- United States
(2, 7), -- Ohio (leaf)
(3, 2), -- North America
(3, 3), -- United States (leaf)
(4, 2), -- North America
(4, 3), -- United States
(4, 4), -- California (leaf)
(4, 7), -- Ohio
(4, 9); -- Toledo (leaf)
I’m trying to create a query the selects the records from @EventLocations that I have identified as leaf nodes. These are records, per event, that have no descendants in relation to the @Locations hierarchy. So it’s possible for a location to be a “leaf” in @EventLocations, but have a descendant in @Locations. I've tried the query below but it only pulls out records that are leafs in the @Locations table.
select ep.EventID, p.*, p2.*
from @EventLocations ep
inner join @Locations p on ep.LocationID = p.LocationID
left outer join @Locations p2 on p.LocationNodeID = p2.LocationNodeID.GetAncestor(1)
where p2.LocationID is null
order by ep.EventID, ep.LocationID