powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Собрать дерево вхождений
10 сообщений из 10, страница 1 из 1
Собрать дерево вхождений
    #39861197
Gamlex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день.

В базе данных на MS SQL есть таблица, смысл которой показать вхождения одних компонентов в другие. К примеру:

Id IdIn
1 2
1 3
2 4
3 5
5 8
5 19
...

Столбец Id - Id компонента, IdIn показывает какие компоненты входят в компонент Id

В программе нужно построить дерево вхождений где верхушкой является определённый компонент. Например, 1й компонент раскрывается на 2 и 3, во втором видим 4, в третьем 5.

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

Учитывая, что таких вхождений может быть до 400, а подключение к базе происходит через интернет, возможны большие задержки в формировании.

ВОПРОС: По сути мне нужны все ID которые напрямую или через другие компоненты входят в компонент с нужным ID. Можно ли как то это реализовать с помощью хранимой процедуры, функции, или может быть это можно сделать единым запросом? Много думал как это сделать, но к сожалению безуспешно. Прошу помочь.
...
Рейтинг: 0 / 0
Собрать дерево вхождений
    #39861205
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Собрать дерево вхождений
    #39861271
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если у вас - заведомое дерево, то можно обойтись рекурсивным запросом, как выше указал Akina .
Однако, если у вас в цепочке есть петли (например, это может быть ошибкой бизнес-логики), то одним запросом - не получится.
Если только у вас не 2019 и вы не храните всё это в виде графа.
...
Рейтинг: 0 / 0
Собрать дерево вхождений
    #39861272
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm , конечно же, прошу прощения.
...
Рейтинг: 0 / 0
Собрать дерево вхождений
    #39861317
Minamoto
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggsterОднако, если у вас в цепочке есть петли (например, это может быть ошибкой бизнес-логики), то одним запросом - не получится.Получится.
...
Рейтинг: 0 / 0
Собрать дерево вхождений
    #39861319
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggsterесли у вас в цепочке есть петли (например, это может быть ошибкой бизнес-логики), то одним запросом - не получитсяЕму нужны не полные пути, а голый список, в этом случае рекурсия в CTE нормально завершится после выбора всех узлов. Просто нужно в рекурсивной части отсекать то, что уже есть.
...
Рейтинг: 0 / 0
Собрать дерево вхождений
    #39861480
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MinamotouaggsterОднако, если у вас в цепочке есть петли (например, это может быть ошибкой бизнес-логики), то одним запросом - не получится.Получится.
А как?
Например:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
Create table #t (id_parent int not null, id_child int not null, primary key clustered (id_parent, id_child))

insert into #t (id_parent, id_child)
values
(1, 2),
(2, 2),
(2, 3),
(2, 4),
(4, 3),
(3, 1),
(5, 5),
(5, 6),
(5, 7),
(7, 5),
(8, 8)


Должно получиться:
1, 2, 3, 4
5, 6, 7
8
...
Рейтинг: 0 / 0
Собрать дерево вхождений
    #39861524
Minamoto
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggsterДолжно получиться:
1, 2, 3, 4
5, 6, 7
8
Не, в постановке автора
GamlexВ программе нужно построить дерево вхождений где верхушкой является определённый компонент.

uaggsterMinamotoпропущено...
Получится.
А как?


Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
WITH cte AS
(
    SELECT id_parent,
           id_child, 
           CAST('/' + CAST(id_parent AS varchar(max)) + '/' AS varchar(MAX)) AS path
    FROM #t
    WHERE id_parent = 1
    UNION ALL
    SELECT t.id_parent, 
           t.id_child, 
           CAST(cte.path + CAST(t.id_parent AS varchar(MAX)) + '/' AS varchar(max))
    FROM   cte
            INNER JOIN #t t ON cte.id_child = t.id_parent
    WHERE   cte.path NOT LIKE '%/' + CAST(t.id_parent AS varchar(MAX)) + '/%'
)
SELECT id_parent, cte.id_child
FROM cte
...
Рейтинг: 0 / 0
Собрать дерево вхождений
    #39861588
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Minamoto, а, понятно.
Это я - вылил воду из чайника и попытался свести задачу к предыдущей.
:-)
...
Рейтинг: 0 / 0
Собрать дерево вхождений
    #39861635
Gamlex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Большое спасибо за ответы! Буду разбираться.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Собрать дерево вхождений
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]