Получить иерархию подразделений в запросе

1. red80 19.10.17 10:28 Сейчас в теме
Добрый день господа.

Необходимо получить таблицу в которой каждому подразделению (элементу справочника с иерархией элементов) будут сопоставлены все подразделения входящие в него на любом уровне вложенности. То-есть вся иерархия подразделений.

Например есть иерархия:
Подр1
+-Подр2
| +-Подр3
| | +-Подр4

Получим :
Подр1 Подр2
Подр1 Подр3
Подр1 Подр4
Подр2 Подр3
Подр2 Подр4
Подр3 Подр4
....................................

Можно такое сделать в одном запросе?
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. DarkUser 19.10.17 10:34 Сейчас в теме
Сделайте подзапрос подразделений с пустым Родителем, и ещё один подзапрос с подразделениями у которых Родитель заполнен. А потом соедините левым соединением две полученных таблицы с условием Таблица2.Подразделение В ИЕРАРХИИ(Таблица1.Подразделение).
3. red80 19.10.17 10:44 Сейчас в теме
(2) Конструктор запроса выдает ошибку :
{(7, 39)} Неверные параметры "В ИЕРАРХИИ"
ПО Подразделения2.Ссылка В ИЕРАРХИИ(Подразделения1.Ссылка)
4. DarkUser 19.10.17 10:46 Сейчас в теме
(3) А, там Таблица1 должна быть не ссылкой а таблицей из одной колонки (с типом Подразделение.Ссылка)
5. red80 19.10.17 10:48 Сейчас в теме
(4) Напишите пожалуйста запрос
6. red80 19.10.17 10:49 Сейчас в теме
(4) Подразделения1.Ссылка не может считаться таблицей из одной колонки? Надо делать временную таблицу?
7. DarkUser 19.10.17 10:54 Сейчас в теме
(6) Он должен быть СпискомЗначений или Таблицей. Сейчас запросик накидаю в чистой конфе.
8. herfis 499 19.10.17 11:03 Сейчас в теме
В универсальном для любого количества уровней - нельзя.
9. red80 19.10.17 11:12 Сейчас в теме
(8) Вы меня расстраиваете.
11. herfis 499 19.10.17 11:30 Сейчас в теме
(9) Что поделать. Работа с древовидными структурами плохо ложится на реляционную алгебру :)
13. DarkUser 19.10.17 11:46 Сейчас в теме
(11) Да Вы правы, универсального запроса не сделать, по крайней мере у меня не получилось.
(1) Извините что ввел в заблуждение.

Однако, получилось сделать запрос с фиксированным количеством вложенных группировок:

ВЫБРАТЬ
	Элементы.Родитель КАК Родитель,
	Элементы.Подгруппа КАК Подгруппа
ИЗ
	(ВЫБРАТЬ
		Родители.Ссылка КАК Родитель,
		Подчиненные.Подгруппа КАК Подгруппа,
		Подчиненные.Родитель КАК РодительПодгруппы
	ИЗ
		Справочник.Подразделение КАК Родители
			ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
				Подразделение.Ссылка КАК Подгруппа,
				Подразделение.Родитель КАК Родитель
			ИЗ
				Справочник.Подразделение КАК Подразделение
			ГДЕ
				Подразделение.Родитель <> ЗНАЧЕНИЕ(Справочник.Подразделение.ПустаяСсылка)
				И Подразделение.ПометкаУдаления = ЛОЖЬ) КАК Подчиненные
			ПО (Подчиненные.Родитель В ИЕРАРХИИ
					(ВЫБРАТЬ
						Подгруппы.Родитель
					ИЗ
						Справочник.Подразделение КАК Подгруппы
					ГДЕ
						Подгруппы.Родитель <> ЗНАЧЕНИЕ(Справочник.Подразделение.ПустаяСсылка)
						И Подгруппы.ПометкаУдаления = ЛОЖЬ))
	ГДЕ
		Родители.Родитель = ЗНАЧЕНИЕ(Справочник.Подразделение.ПустаяСсылка)
		И Родители.ПометкаУдаления = ЛОЖЬ) КАК Элементы
ГДЕ
	(Элементы.РодительПодгруппы В (Элементы.Родитель)
			ИЛИ Элементы.РодительПодгруппы.Родитель В (Элементы.Родитель)
			ИЛИ Элементы.РодительПодгруппы.Родитель.Родитель В (Элементы.Родитель)
			ИЛИ Элементы.РодительПодгруппы.Родитель.Родитель.Родитель В (Элементы.Родитель)
			ИЛИ Элементы.РодительПодгруппы.Родитель.Родитель.Родитель.Родитель В (Элементы.Родитель))

УПОРЯДОЧИТЬ ПО
	Родитель,
	Подгруппа
АВТОУПОРЯДОЧИВАНИЕ
Показать


Правда на уровне SQL наверное там страшный код будет...
10. red80 19.10.17 11:18 Сейчас в теме
14. red80 19.10.17 11:50 Сейчас в теме
Спасибо всем принявшим участие, пошел делать как в https://infostart.ru/public/158512/
15. herfis 499 19.10.17 11:56 Сейчас в теме
(14) Нафига? У тебя же более простая задача. Просто получи запросом все подразделения с их прямыми родителями и итерационно в коде сможешь сформировать нужную таблицу без повторных обращений к БД.
17. red80 19.10.17 12:03 Сейчас в теме
(15) Ну, это надо код писать.
16. herfis 499 19.10.17 11:58 Сейчас в теме
Хотя, чтобы не тащить на клиента... Можно и запросами в цикле через менеджер временных таблиц.
Не. Туплю, там же речь о динамическом формировании одного запроса в цикле, а не циклическом выполнении.
18. user1119934 27.12.18 07:56 Сейчас в теме
Предлагаю изящное решение с применением рекурсии

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

&НаСервере
Процедура ВыборОтделенийВИерархии(Подразделение)
	
	СписокОтделений.Добавить( Подразделение );           //  Выводим сразу в Список Значений
	
	Запрос = Новый Запрос;
	Текст = 
	"ВЫБРАТЬ РАЗЛИЧНЫЕ
	|		Отделения.Ссылка  КАК Ссылка
	|			ИЗ
	|		Справочник.СтруктураПредприятия КАК Отделения
	|       	ГДЕ
	|       Отделения.Родитель =  &Подразделение         // Выбираем подразделения у которых исходное является родителем
	|";
	
	Запрос.УстановитьПараметр("Подразделение", Подразделение);
		
	Запрос.Текст = Текст;
	РезультатЗапроса = Запрос.Выполнить().Выбрать();
	
	Если РезультатЗапроса.Количество() > 0 Тогда
		Пока РезультатЗапроса.Следующий() Цикл		
			ВыборОтделенийВИерархии(РезультатЗапроса.Ссылка);	//   В каждом из подчиненных подразделений в свою очередь ищем вложенных
		КонецЦикла;
	КонецЕсли;		
КонецПроцедуры
Показать
HIVvich; Hogyoku; +2 Ответить
19. HIVvich 15.06.23 11:47 Сейчас в теме
(18)
Процедура ВыборОтделенийВИерархии(Подразделение)

СписокОтделений.Добавить( Подразделение ); // Выводим сразу в Список Значений

Запрос = Новый Запрос;
Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Отделения.Ссылка КАК Ссылка
| ИЗ
| Справочник.СтруктураПредприятия КАК Отделения
| ГДЕ
| Отделения.Родитель = &Подразделение // Выбираем подразделения у которых исходное является родителем
|";

Запрос.УстановитьПараметр("Подразделение", Подразделение);

Запрос.Текст = Текст;
РезультатЗапроса = Запрос.Выполнить().Выбрать();

Если РезультатЗапроса.Количество() > 0 Тогда
Пока РезультатЗапроса.Следующий() Цикл
ВыборОтделенийВИерархии(РезультатЗапроса.Ссылка); // В каждом из подчиненных подразделений в свою очередь ищем вложенных
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Показать

Отлично, спасибо!
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот