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

时间:2020-09-17 13:21:07

标签: sql-server tsql

我需要基于NR和NR_FROM-NR_TO计算“层次结构”列,我不确定如何使用此类层次结构列创建CTE / VIEW。结果应该是这样的:

+------+----------------------+---------+-------+---------------------------+
|  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 | /                         |
+------+----------------------+---------+-------+---------------------------+

1 个答案:

答案 0 :(得分:2)

看起来像这种解决方案可以满足您的需求。

样本数据

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;

https://www.ag-grid.com/javascript-grid-cell-rendering-components/#accessing-cell-renderer-instances