简体   繁体   English

匹配 id 或 masterid 或 masterid 的 masterid 等

[英]Match id or masterid or masterid of masterid etc

I have a Location table:我有一个位置表:

Id int
MasterLocationId int
Name varchar(50)

A location can have a master location and so on.一个位置可以有一个主位置等等。 There's no specific limit to how many levels this could be.这可能是多少级别没有具体限制。

How can I search for any locations with a certain ID, or locations where a master record has that ID, or its master record has that ID - and so on.如何搜索具有特定 ID 的任何位置,或主记录具有该 ID 的位置,或其主记录具有该 ID - 等等。

I'm not really sure what to even search for on Google here - perhaps this type of situation has a name and I'm not sure what it's called?我真的不确定在 Google 上搜索什么 - 也许这种情况有一个名字,我不确定它叫什么?

I've searched for recursive TSQL and couldn't find anything.我搜索了递归 TSQL 并且找不到任何东西。

Is this possible?这可能吗?

Thanks谢谢

As @Isaac and @Jeroen said in comments, recursive CTE is what you need.正如@Isaac@Jeroen在评论中所说,递归CTE 是您所需要的。

Sample data:样本数据:

CREATE TABLE Locations (
    Id int,
    MasterLocationId int,
    Name varchar(50)
);

insert into Locations (Id, Name, MasterLocationId)
values 
    (1, 'Alice',   null),
    (2, 'Bob',     1),
    (3, 'Charlie', 2),
    (4, 'Dave',    3),
    (5, 'Erin',    4),
    (6, 'Frank',   5),
    (7, 'Grace',   6),
    (8, 'Heidi',   7),
    (9, 'Ivan',    8),
    (10,'Judy',    9),
    (11,'Kevin',   10),
    (12,'Lucy',    6),
    (13,'Mike',    7),
    (14,'Noah',    8),
    (15,'Olivia',  9),
    (16,'Peggy',   10),
    (17,'Rupert',  6),
    (18,'Sybil',   7),
    (19,'Ted',     8),
    (20,'Trudy',   9),
    (21,'Uma',     10),
    (22,'Victor',  11),
    (23,'Walter',  22),
    (24,'Xavier',  23),
    (25,'Yves',    24),
    (26,'Zoe',     25);

And a query:和一个查询:

;
with Locations_CTE as (
    -- anchor of 1st tier parents
    select L1.Id, L1.Name, L1.MasterLocationId, L2.Name as MasterLocationName, 1 as MasterLocationTier
    from Locations as L1
        left join Locations as L2
            on L1.MasterLocationId = L2.Id
    -- recursive part
    union all
    select L1.Id, L1.Name, L2.MasterLocationId, L3.Name as MasterLocationName, L1.MasterLocationTier + 1 as MasterLocationTier
    from Locations_CTE as L1
        inner join Locations as L2
            on L1.MasterLocationId = L2.Id
        inner join Locations as L3
            on L2.MasterLocationId = L3.Id
)

select * 
from Locations_CTE
where MasterLocationId = 11 -- Find all locations which have Kevin as MasterLocation somewhere in a hierarchy.
or Id = 11                  -- And full hierarchy for Kevin
order by Id, MasterLocationTier

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM