都市/地域/国/大陸をマッピングするために hierarchyid 列を使用する Locations テーブルがあります。テーブルは次のようになります。
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');
イベントを場所にマップする 2 つ目のテーブルがあります。このテーブルは階層を平坦化し、レベルごとに 1 つのレコードを持ちます (この方法で継承しました)。したがって、イベントがロサンゼルスで行われる場合、このテーブルにはイベントの 4 つのレコード (ロサンゼルス、カリフォルニア、米国、北米) があります。同じイベントを複数の場所で開催することもできます。
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)
リーフ ノードとして識別した @EventLocations からレコードを選択するクエリを作成しようとしています。これらは、@Locations 階層に関連する子孫を持たないイベントごとのレコードです。したがって、場所が @EventLocations の「葉」である可能性がありますが、@Locations に子孫があります。以下のクエリを試してみましたが、@Locations テーブルのリーフであるレコードのみが抽出されます。
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