2013-09-20 4 views
1

Рассмотрим эту таблицу:TSQL создать оборванный иерархию из плоской структуры

declare @table as table (
    GL_Group_Code varchar(8), 
    GL_Branch_Code varchar(8), 
    Account_Number varchar(4), 
    GL_Centre_Number varchar(6) 
) 

insert into @table 
select '0100', '0110', '1200', 'S10118' union 
select '0100', '0110', '1580', 'S16053' union 
select '0200', '0210', '2050', '200049' union 
select '0200', '0210', '2050', '782844' 

Желаемый результат является родителем ребенка отношения через четыре исходных столбцов в:

declare @table_hier as table (
    Parent_ID varchar(8), 
    Item_ID  varchar(8) 
) 

С того отношения колонны 1 , 2,3,4 результат для первой строки из исходной таблицы будет выглядеть так:

null 0100 
0100 0110 
0110 1200 
1200 S10118 

Вторая строка будет выглядеть так:

null 0100 
0100 0110 
0110 1580 
1580 S16053 

порядок отношения могут варьироваться в зависимости: 1,2,4,3 или 3,4 или 1,3,4

Я думаю рекурсивный КТР однако поздно на Пятницу я мог сделать с небольшой помощью.

+0

вам нужно создать фиксированный или иметь структуру по требованию делать? –

+0

По требованию действительно может пойти с фиксированным однако, что требует обслуживания –

ответ

0

Если вы можете иметь идентификатор в таблице и использовать табличную переменную для хранения столбцы, которые вы хотите получить, вы можете сделать это:

declare @ord table (id int) 

insert into @ord 
values (1), (2), (4) 

;with cte as (
    select 
     t.id, 
     c.value, 
     row_number() over(partition by t.id order by c.id) as rn 
    from @table as t 
     cross apply (
      values 
       (1, t.GL_Group_Code), 
       (2, t.GL_Branch_Code), 
       (3, t.Account_Number), 
       (4, t.GL_Centre_Number) 
     ) as c(id, value) 
    where 
     exists (select * from @ord as o where o.id = c.id) 
) 
insert into @table_hier 
select 
    c1.value as Parent_ID, c2.value as Item_ID 
from cte as c1 
    inner join cte as c2 on c2.rn = c1.rn + 1 and c2.id = c1.id 
order by c1.rn 

insert into @table_hier 
select null, t.Parent_ID 
from @table_hier as t 
where 
    not exists 
    (
     select * 
     from @table_hier as t2 
     where t2.Item_ID = t.Parent_ID 
    ) 


select * from @table_hier 

sql fiddle demo

Или если вы можете хранить свои данные в таблицах o г временных таблиц, вы можете использовать динамическое решение SQL:

declare @ord table (id int) 
declare @stmt nvarchar(max) 

insert into @ord 
values (1), (2), (4) 

;with cte as (
select c.name, row_number() over(order by c.colid) as rn 
from sys.syscolumns as c 
where 
    c.id = object_id('dbo.table1') and 
    exists (select * from @ord as o where o.id = c.colid) 
) 
select @stmt = 
    isnull(@stmt + ', ', '') + 
    '(' + c1.name + ', ' + c2.name + ')' 
from cte as c1 
    inner join cte as c2 on c2.rn = c1.rn + 1 
order by c1.rn 

select @stmt = ' 
    insert into table_hier1 
    select C.Parent_ID, C.Item_ID 
    from table1 as t 
     cross apply (
      values ' + @stmt + ' 
     ) as C(Parent_ID, Item_ID) 
' 

exec sp_executesql 
    @stmt = @stmt 

insert into table_hier1 
select null, t.Parent_ID 
from table_hier1 as t 
where 
    not exists 
    (
     select * 
     from table_hier1 as t2 
      where t2.Item_ID = t.Parent_ID 
    ) 

select * from table_hier1 

sql fiddle demo

0

попробовать что-то вроде этого

declare @table as table (
    GL_Group_Code varchar(8), 
    GL_Branch_Code varchar(8), 
    Account_Number varchar(4), 
    GL_Centre_Number varchar(6) 
) 

insert into @table 
select '0100', '0110', '1200', 'S10118' union 
select '0100', '0110', '1580', 'S16053' union 
select '0200', '0210', '2050', '200049' union 
select '0200', '0210', '2050', '782844' 

declare @table_hier as table (
    Parent_ID varchar(8), 
    Item_ID  varchar(8) 
) 

DECLARE @RelatonShip VARCHAR(4) 

SET @RelatonShip = '134' 

IF @RelatonShip = '1234' 
BEGIN 
    INSERT INTO @table_hier (Parent_ID, Item_ID) 
    SELECT GL_Group_Code, GL_Branch_Code FROM @table 
    UNION ALL SELECT GL_Branch_Code, Account_Number FROM @Table 
    UNION ALL SELECT Account_Number, GL_Centre_Number FROM @table 
END 
IF @RelatonShip = '1243' 
BEGIN 
    INSERT INTO @table_hier (Parent_ID, Item_ID) 
    SELECT GL_Group_Code, GL_Branch_Code FROM @table 
    UNION ALL SELECT GL_Branch_Code, GL_Centre_Number FROM @Table 
    UNION ALL SELECT GL_Centre_Number, Account_Number FROM @table 
END 
IF @RelatonShip = '34' 
BEGIN 
    INSERT INTO @table_hier (Parent_ID, Item_ID) 
    SELECT Account_Number, GL_Centre_Number FROM @table 
END 
IF @RelatonShip = '134' 
BEGIN 
    INSERT INTO @table_hier (Parent_ID, Item_ID) 
    SELECT GL_Group_Code, Account_Number FROM @table 
    UNION ALL SELECT Account_Number, GL_Centre_Number FROM @table 
END 

SELECT * FROM @table_hier 
Смежные вопросы