Sql server T-SQL计算层次结构/父级

Sql server T-SQL计算层次结构/父级,sql-server,tsql,Sql Server,Tsql,我需要根据NR和NR_FROM-NR_to计算层次结构列,我不确定如何使用这样的层次结构列创建CTE/视图。结果应该是这样的: +------+----------------------+---------+-------+---------------------------+ | NR | Text | NR_FROM | NR_TO | HIERARCHY | +------+----------------------

我需要根据NR和NR_FROM-NR_to计算层次结构列,我不确定如何使用这样的层次结构列创建CTE/视图。结果应该是这样的:

+------+----------------------+---------+-------+---------------------------+
|  NR  |         Text         | NR_FROM | NR_TO |         HIERARCHY         |
+------+----------------------+---------+-------+---------------------------+
| 1020 | AAAAAAAAAAAA         |         |       | /1380/1345/1300/1080/1051 |
| 1040 | BBBBBBB              |         |       | /1380/1345/1300/1080/1051 |
| 1045 | CCCCCCCCCCCCCCCCCCC  |         |       | /1380/1345/1300/1080/1051 |
| 1051 | DDDDDDDDDDD          |    1020 |  1045 | /1380/1345/1300/1080      |
| 1060 | EEEEEE               |         |       | /1380/1345/1300/1080      |
| 1080 | FFFF                 |    1051 |  1060 | /1380/1345/1300/1092      |
| 1090 | GGGGGGGGGGGGGGGG     |         |       | /1380/1345/1300/1092      |
| 1090 | So. betr. Erlöse     |         |       | /1380/1345/1300/1092      |
| 1092 | Betriebl. Rohertrag  |    1080 |  1090 | /1380/1345/1300           |
| 1100 | Abschreibungen       |         |       | /1380/1345/1300/1280      |
| 1100 | Abschreibungen       |         |       | /1380/1345/1300/1280      |
| 1110 | Personalk. Basis     |         |       | /1380/1345/1300/1280      |
| 1110 | Personalk. Basis     |         |       | /1380/1345/1300/1280      |
| 1120 | Personalk. Zusatz    |         |       | /1380/1345/1300/1280      |
| 1264 | Beratungsaufwand     |         |       | /1380/1345/1300/1280      |
| 1265 | sonstiger Aufwand    |         |       | /1380/1345/1300/1280      |
| 1280 | Gesamtkosten         |    1100 |  1265 | /1380/1345/1300           |
| 1300 | EBIT                 |    1000 |  1280 | /1380/1345                |
| 1310 | Zinsaufwand          |         |       | /1380/1345                |
| 1312 | Sonst. neutr. Aufw   |         |       | /1380/1345                |
| 1320 | Neutraler Aufwand    |    1310 |  1312 | /1380/1345                |
| 1322 | Zinserträge          |         |       | /1380/1345/1330           |
| 1323 | Sonst. neutr. Ertr   |         |       | /1380/1345/1330           |
| 1324 | Verr. kalk. Kosten   |         |       | /1380/1345/1330           |
| 1330 | Neutraler Ertrag     |    1322 |  1324 | /1380/1345                |
| 1345 | DSDSDSDSDSDD         |    1300 |  1320 | /1380                     |
| 1345 | DSDSDSDSDSDD         |    1330 |  1330 | /1380                     |
| 1355 | FDSFDSFSDFDSFSFSD    |         |       | /1380                     |
| 1380 | DDDAAA               |    1345 |  1355 | /                         |
+------+----------------------+---------+-------+---------------------------+

看起来这个解决方案可以满足您的需要

样本数据

解决方案


NR、NR_FROM、NR_to和层次结构之间似乎没有相关性。请编辑该问题,以包括您迄今为止尝试过的SQL代码以及相关架构和示例数据。anchor是在任何from到之间不存在的Nr…每个成员都有Nr介于from到之间的所有子项:根是通过排除Nr从到Nr从任何范围内的所有Nr行来找到的。在你的CTE锚里。然后,根据NR_From和NR_TO递归地添加行。如果您提供了可用数据,例如将@Samples声明为表。。。;插入到@Samples。。。价值观提供一个工作示例会容易得多。您的结果以/1345开始层次结构,而不是像OP的预期结果那样以/1380开始层次结构。@HABO,很好。现在应该修好了。仍然没有和奥普的结果100%的匹配,但我不认为这是在我这边。Nr 1020生成层次结构/1380/1345/1300/1092/1080/1051。我认为OP在他的预期结果中忘记了1092,1092是[10801090]的父对象。嘿,看起来很棒,我还没试过。是的,我的错,少了1092个。塔克斯
create table ranges
(
  nr int,
  txt nvarchar(20),
  nr_from int,
  nr_to int
);

insert into ranges (nr, txt, nr_from, nr_to) values
(1020, 'AAAAAAAAAAAA       ', null, null),
(1040, 'BBBBBBB            ', null, null),
(1045, 'CCCCCCCCCCCCCCCCCCC', null, null),
(1051, 'DDDDDDDDDDD        ', 1020, 1045),
(1060, 'EEEEEE             ', null, null),
(1080, 'FFFF               ', 1051, 1060),
(1090, 'GGGGGGGGGGGGGGGG   ', null, null),
(1090, 'So. betr. Erlöse   ', null, null),
(1092, 'Betriebl. Rohertrag', 1080, 1090),
(1100, 'Abschreibungen     ', null, null),
(1100, 'Abschreibungen     ', null, null),
(1110, 'Personalk. Basis   ', null, null),
(1110, 'Personalk. Basis   ', null, null),
(1120, 'Personalk. Zusatz  ', null, null),
(1264, 'Beratungsaufwand   ', null, null),
(1265, 'sonstiger Aufwand  ', null, null),
(1280, 'Gesamtkosten       ', 1100, 1265),
(1300, 'EBIT               ', 1000, 1280),
(1310, 'Zinsaufwand        ', null, null),
(1312, 'Sonst. neutr. Aufw ', null, null),
(1320, 'Neutraler Aufwand  ', 1310, 1312),
(1322, 'Zinserträge        ', null, null),
(1323, 'Sonst. neutr. Ertr ', null, null),
(1324, 'Verr. kalk. Kosten ', null, null),
(1330, 'Neutraler Ertrag   ', 1322, 1324),
(1345, 'DSDSDSDSDSDD       ', 1300, 1320),
(1345, 'DSDSDSDSDSDD       ', 1330, 1330),
(1355, 'FDSFDSFSDFDSFSFSD  ', null, null),
(1380, 'DDDAAA             ', 1345, 1355);
with cte as
(
  select r.nr, r.txt, r.nr_from, r.nr_to, 1 as lvl, convert(nvarchar(100), '') as hierarchy
  from ranges r
  where not exists ( select 'x'
                     from ranges r2
                     where r2.nr_from <= r.nr
                       and r2.nr_to >= r.nr)
    union all
  select r.nr, r.txt, r.nr_from, r.nr_to, lvl+1, convert(nvarchar(100), cte.hierarchy + '/' + convert(nvarchar(4), cte.nr))
  from ranges r
  join cte
    on  cte.nr_from <= r.nr
    and cte.nr_to >= r.nr
)
select cte.nr,
       cte.txt,
       cte.nr_from,
       cte.nr_to,
       case when cte.lvl = 1 then '/' else cte.hierarchy end as hierarchy
from cte
where not exists ( select 'x'
                   from cte c2
                   where c2.nr = cte.nr
                     and c2.lvl > cte.lvl )
order by cte.nr;