Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
Gamlex Member Откуда: Сообщений: 18 |
Добрый день. В базе данных на 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. Можно ли как то это реализовать с помощью хранимой процедуры, функции, или может быть это можно сделать единым запросом? Много думал как это сделать, но к сожалению безуспешно. Прошу помочь. |
12 сен 19, 22:51 [21969926] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9633 |
https://www.google.ru/search?q=ms sql рекурсивные запросы |
12 сен 19, 23:00 [21969935] Ответить | Цитировать Сообщить модератору |
uaggster Member Откуда: Сообщений: 952 |
Если у вас - заведомое дерево, то можно обойтись рекурсивным запросом, как выше указал Akina. Однако, если у вас в цепочке есть петли (например, это может быть ошибкой бизнес-логики), то одним запросом - не получится. Если только у вас не 2019 и вы не храните всё это в виде графа. |
13 сен 19, 08:54 [21970034] Ответить | Цитировать Сообщить модератору |
uaggster Member Откуда: Сообщений: 952 |
invm, конечно же, прошу прощения. |
13 сен 19, 08:55 [21970035] Ответить | Цитировать Сообщить модератору |
Minamoto Member Откуда: Москва Сообщений: 1162 |
|
||
13 сен 19, 09:51 [21970104] Ответить | Цитировать Сообщить модератору |
Akina Member Откуда: Зеленоград, Москва, Россия Сообщений: 20960 |
|
||
13 сен 19, 09:53 [21970108] Ответить | Цитировать Сообщить модератору |
uaggster Member Откуда: Сообщений: 952 |
А как? Например: 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 |
||||
13 сен 19, 13:23 [21970288] Ответить | Цитировать Сообщить модератору |
Minamoto Member Откуда: Москва Сообщений: 1162 |
Не, в постановке автора
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 |
||||||||
13 сен 19, 13:59 [21970344] Ответить | Цитировать Сообщить модератору |
uaggster Member Откуда: Сообщений: 952 |
Minamoto, а, понятно. Это я - вылил воду из чайника и попытался свести задачу к предыдущей. :-) |
13 сен 19, 14:55 [21970435] Ответить | Цитировать Сообщить модератору |
Gamlex Member Откуда: Сообщений: 18 |
Большое спасибо за ответы! Буду разбираться. |
13 сен 19, 15:57 [21970506] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |