#sql-server #tsql
#sql-сервер #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. Похоже, что нет корреляции между NR, NR_FROM, NR_TO и ИЕРАРХИЕЙ. Пожалуйста, отредактируйте вопрос, чтобы включить код SQL, который вы пробовали до сих пор, вместе с соответствующей схемой и образцами данных.
2. привязка — это номер, который не существует ни между одним из … у каждого члена есть все дочерние элементы с номером между от-до
3. SWAG : корень найден путем исключения всех строк с
NR
в любом из диапазонов отNR_FROM
доNR_TO
. Это входит в ваш якорь CTE. Оттуда рекурсивно добавляются строки на основеNR_FROM
иNR_TO
. Если бы вы предоставили полезные данные, напримерdeclare @Samples as Table ( ...); insert into @Samples ( ... ) values ...;
, было бы намного проще предоставить рабочий пример.
Ответ №1:
Похоже, это решение дает вам то, что вам нужно.
Пример данных
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;
Комментарии:
1. Ваши результаты начинают иерархию с
/1345
, а не/1380
как в ожидаемых результатах OP.2. @HABO, хороший улов. Должно быть исправлено сейчас. Все еще не на 100% совпадает с результатом OP, но я не думаю, что это на моей стороне сейчас. Nr
1020
создает иерархию/1380/1345/1300/1092/1080/1051
. Я думаю, что OP забыл1092
в своем ожидаемом результате (1092
является родительским для [1080
,1090
]).3. Эй, выглядит великолепно (еще не пробовал). Да, моя ошибка, не хватает 1092. Спасибо