Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Собрать дерево вхождений / 10 сообщений из 10, страница 1 из 1
12.09.2019, 22:51
    #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
12.09.2019, 23:00
    #39861205
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать дерево вхождений
...
Рейтинг: 0 / 0
13.09.2019, 08:54
    #39861271
uaggster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать дерево вхождений
Если у вас - заведомое дерево, то можно обойтись рекурсивным запросом, как выше указал Akina .
Однако, если у вас в цепочке есть петли (например, это может быть ошибкой бизнес-логики), то одним запросом - не получится.
Если только у вас не 2019 и вы не храните всё это в виде графа.
...
Рейтинг: 0 / 0
13.09.2019, 08:55
    #39861272
uaggster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать дерево вхождений
invm , конечно же, прошу прощения.
...
Рейтинг: 0 / 0
13.09.2019, 09:51
    #39861317
Minamoto
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать дерево вхождений
uaggsterОднако, если у вас в цепочке есть петли (например, это может быть ошибкой бизнес-логики), то одним запросом - не получится.Получится.
...
Рейтинг: 0 / 0
13.09.2019, 09:53
    #39861319
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать дерево вхождений
uaggsterесли у вас в цепочке есть петли (например, это может быть ошибкой бизнес-логики), то одним запросом - не получитсяЕму нужны не полные пути, а голый список, в этом случае рекурсия в CTE нормально завершится после выбора всех узлов. Просто нужно в рекурсивной части отсекать то, что уже есть.
...
Рейтинг: 0 / 0
13.09.2019, 13:23
    #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
13.09.2019, 13:59
    #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
13.09.2019, 14:55
    #39861588
uaggster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать дерево вхождений
Minamoto, а, понятно.
Это я - вылил воду из чайника и попытался свести задачу к предыдущей.
:-)
...
Рейтинг: 0 / 0
13.09.2019, 15:57
    #39861635
Gamlex
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать дерево вхождений
Большое спасибо за ответы! Буду разбираться.
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Собрать дерево вхождений / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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