Как создать скрипт для типа данных иерархии для данных ниже? - PullRequest
2 голосов
/ 24 января 2020

Не могли бы вы помочь мне в отношении моего столбца hierarchyid типа данных как orgpath?

У меня есть таблица с названием companies, в которой значения companyid, parentcompany_id, companyName - это поля, которые мне нужны для создания "orgpath "как иерархия.

declare @Companies table (
    Company_ID uniqueidentifier,
    CompanyName nvarchar(50),
    ParentCompany_ID uniqueidentifier
);

insert into @Companies 
    (Company_ID,                              ParentCompany_ID,                        CompanyName                        )
values
    ('826FDFF6-E1FC-44BA-94A1-000ACEAAA8D0', '8EDB58B8-7F5C-45D1-A1BF-0004DA969109', N'BAY'                               ),            
    ('89F2A314-2C1D-44BD-84EF-00120905B95D', '671E53DE-EFBC-4D16-993B-A2BB99970A1E', N'Kuehne + Nagel AS, Stvg'           ), 
    ('088C557C-0B5F-4D9F-849E-002B3E19F8B2', '69064F08-E87C-4219-9032-25E1084B25AB', N'Quasar Energy Services'            ), 
    ('D4ADD17D-D9D8-435E-AF42-0036F67D07A7', 'E9762391-6A3A-4753-B545-0D83B6FDDC1E', N'Bryan District'                    ), 
    ('2F345CAC-2951-4B1A-9036-0037A2E3CDCE', '8C73A17C-A7F9-4E5F-B8C3-18FD8AD83216', N'BAY OFFSHORE'                      ),     
    ('5481F3FC-6384-4147-B3FB-0040BCFFB7F6', '49132BF4-2003-430E-96C8-112EE717659B', N'CETCO/NEW IBERIA'                  ),     
    ('7ABBC4C8-4196-45DC-8D05-005111BF5DDD', 'A0F84712-5D0B-48A8-9C46-D76CDC38AAAD', N'Houston Washline'                  ),     
    ('473689A9-DEB3-4D6D-B6AC-005C607317BE', 'CA7B6679-1101-4541-A3BF-A440649F17B6', N'Knight Oil Tools Middle East DMCC' ),     
    ('DC4FD87C-72CF-4782-A98A-006C5FC32997', 'A622740E-1154-478D-B917-E29F4337F3CB', N'RIG 57'                            ), 
    ('475D86FD-F8AF-452B-8E91-0070925127F1', '8C73A17C-A7F9-4E5F-B8C3-18FD8AD83216', N'BP AMOCO'                          ); 

select * from @Companies;

Это мои данные в таблице компаний.

with x 
as
(
select ROW_NUMBER() over(partition by parentcompany_id,company_id order by company_id ) as num,* from Companies
)

select * into #temp2 from x

; with compath
as
(
select 
    hierarchyid::GetRoot() as orgpath,
    company_id,
    companyname,
    parentcompany_id
from
    #temp2
where
    1=1 and ParentCompany_ID is null

union all

select 
    cast(p.Orgpath.ToString() + cast(c.Num as varchar(30)) + '/' as hierarchyid),
    c.company_id,c.companyname,c.parentcompany_id
from 
    #temp2 c
    join compath p
        on c.parentcompany_id=p.company_id
)

Select P.*,orgpath.ToString() from compath p; 

1 Ответ

0 голосов
/ 25 января 2020

Кришна, я думаю, что вы дали нам только часть вашей огромной таблицы с иерархическими данными.

Чтобы построить иерархию, значения из ParentCompany_ID должны присутствовать в Company_ID, а root узел должен (в большинстве случаев) быть null.

Я изменил предоставленные вами данные, чтобы они отражали вышеуказанные правила, и ниже приведен скрипт, который, я думаю, вы ищете:

declare @Companies table (
    Company_ID uniqueidentifier,
    CompanyName nvarchar(50),
    ParentCompany_ID uniqueidentifier
);

insert into @Companies 
    (Company_ID,                              ParentCompany_ID,                        CompanyName                        )
values
    ('826FDFF6-E1FC-44BA-94A1-000ACEAAA8D0', null                                  , N'BAY'                               ),            
    ('89F2A314-2C1D-44BD-84EF-00120905B95D', '826FDFF6-E1FC-44BA-94A1-000ACEAAA8D0', N'Kuehne + Nagel AS, Stvg'           ), 
    ('088C557C-0B5F-4D9F-849E-002B3E19F8B2', '826FDFF6-E1FC-44BA-94A1-000ACEAAA8D0', N'Quasar Energy Services'            ), 
    ('D4ADD17D-D9D8-435E-AF42-0036F67D07A7', '89F2A314-2C1D-44BD-84EF-00120905B95D', N'Bryan District'                    ), 
    ('2F345CAC-2951-4B1A-9036-0037A2E3CDCE', '89F2A314-2C1D-44BD-84EF-00120905B95D', N'BAY OFFSHORE'                      ),     
    ('5481F3FC-6384-4147-B3FB-0040BCFFB7F6', '088C557C-0B5F-4D9F-849E-002B3E19F8B2', N'CETCO/NEW IBERIA'                  ),     
    ('7ABBC4C8-4196-45DC-8D05-005111BF5DDD', '088C557C-0B5F-4D9F-849E-002B3E19F8B2', N'Houston Washline'                  ),     
    ('473689A9-DEB3-4D6D-B6AC-005C607317BE', '5481F3FC-6384-4147-B3FB-0040BCFFB7F6', N'Knight Oil Tools Middle East DMCC' ),     
    ('DC4FD87C-72CF-4782-A98A-006C5FC32997', '5481F3FC-6384-4147-B3FB-0040BCFFB7F6', N'RIG 57'                            ), 
    ('475D86FD-F8AF-452B-8E91-0070925127F1', '5481F3FC-6384-4147-B3FB-0040BCFFB7F6', N'BP AMOCO'                          ); 


with Recursion as
(
    select
        Company_ID       ,
        ParentCompany_ID ,
        CompanyName      ,
        orgpath  =  cast('/' as varchar(1000))
    from
        @Companies
    where
        ParentCompany_ID is null

    union all 

    select
        c.Company_ID       ,
        c.ParentCompany_ID ,        
        c.CompanyName      ,
        orgpath =  
            cast(
                concat(
                    r.orgpath, 
                    row_number() over (partition by c.ParentCompany_ID order by c.CompanyName, c.Company_ID), 
                    '/'
                ) 
                as varchar(1000)
            )                    
    from 
        Recursion r        
        inner join @Companies c on c.ParentCompany_ID = r.Company_ID 
)
select *, Hid = hierarchyid::Parse(orgpath) from Recursion;

Полагаю, если вы запустите запрос к полной таблице, вы получите ожидаемый orgpath. (невозможно восстановить полный orgpath, имеющий только небольшое подмножество записей)

Подробнее о HierarchyId в Сочетание подходов Id-ParentId и HierarchyId к иерархическим данным

ОБНОВЛЕНИЕ:

Следующая строка скрипта создает HierarchyId, который упорядочивает компании в пределах его родительского элемента на CompanyName:

row_number() over (partition by c.ParentCompany_ID order by c.CompanyName, c.Company_ID)

Чтобы заказать компании из ветвь по Company_ID, используйте следующую строку:

row_number() over (partition by c.ParentCompany_ID order by c.Company_ID)
...