Форум программистов, компьютерный форум, киберфорум
PostgreSQL
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.68/34: Рейтинг темы: голосов - 34, средняя оценка - 4.68
1 / 1 / 1
Регистрация: 24.03.2013
Сообщений: 177

Update с использованием рекурсивного запроса

10.06.2019, 15:17. Показов 6945. Ответов 2

Студворк — интернет-сервис помощи студентам
Есть иерархическая таблица, поле с иерархией parent_id, нужно заполнить level - уровень вложенности, hier - строка с названиями родителями (исключая корень таблицы), root - значения корня иерархии (если у предка в поле new_root = true, то у потомков в поле root должен быть id этого предка).
Пример можно посмотреть https://www.db-fiddle.com/f/ez... 6rDJgZUo/0

T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CREATE TABLE geo (
    id int not null primary key, 
    parent_id int references geo(id),  
    name varchar(1000),
     level int,
     hier varchar(1000),
    root int,
    new_root bool    
);
 
INSERT INTO geo 
(id, parent_id, name, level, hier,root, new_root) 
VALUES 
(1, null, 'Планета Земля', null, null,null, null),
(2, 1, 'Континент Евразия', null, null,null, null),
(3, 1, 'Континент Северная Америка', null, null,null, null),
(4, 2, 'Европа', null, null,null, null),
(5, 4, 'Россия', null, null,null, true),
(6, 4, 'Германия', null, null,null, null),
(7, 5, 'Москва', null, null,null, null),
(8, 5, 'Санкт-Петербург', null, null,null, null),
(9, 6, 'Берлин', null, null,null, null);
Написал запрос:
T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
WITH RECURSIVE r AS (
   SELECT id, parent_id, name, 2 AS level, null AS hier, 1 as root
   FROM geo
   WHERE parent_id = 1
 
   UNION ALL
 
   SELECT geo.id, geo.parent_id, geo.name, r.level + 1 AS level,  case when r.hier is NULL then (select name from geo tmp where tmp.id=geo.parent_id limit 1) else  r.hier::text || '#' || (select name from geo tmp where tmp.id=geo.parent_id limit 1) end AS hier,
CASE WHEN (SELECT new_root FROM geo tmp WHERE tmp.id=geo.parent_id LIMIT 1) IS true 
   THEN (SELECT id FROM geo tmp WHERE tmp.id=geo.parent_id LIMIT 1)
   ELSE r.root END AS root
   FROM geo inner JOIN r ON (geo.parent_id = r.id)
),
T AS(
select id,  parent_id, name, 1 AS level, null::text AS hier, id as root
from geo
where id = 1
union
SELECT * FROM r
)
Update geo
set(level, hier, root) = (T.level, T.hier, T.root)
from T
where geo.id=T.id;
select *
from geo
Посоветуйте, как можно улучшить запрос???
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.06.2019, 15:17
Ответы с готовыми решениями:

ЗАПРОС С ИСПОЛЬЗОВАНИЕМ РЕКУРСИВНОГО СОЕДИНЕНИЯ
как вы думаете можно создать рекурсивный запрос для таблицы, в которой лежат имена, фамилии, номера телефонов и адреса служателей, виды их...

Выполнение рекурсивного запроса без использования рекурсивных функций
Всем привет. Имеется следующее задание: Для каждого сотрудника выбрать всех его начальников по иерархии. Вывести поля: код...

Написать программу с использованием рекурсивного метода
Напишите приложение, которое строит ряд окружностей. Число окружностей удваивается на каждом шаге (в рекурсивном методе происходит два...

2
 Аватар для Уф
890 / 725 / 447
Регистрация: 13.07.2015
Сообщений: 2,277
13.06.2019, 17:17
не хочешь попробовать materialized path? когда в колонке дерева просто ключи
1
1-1
1-1-2
2
2-1
и тд? работать гораздо удобнее, я тоже пытался сначала сделать дерево через parent id, но там куча велосипедов, каждый раз крутить циклы для вывода, для поиска уровня вложенности и т.д. плюс если случайно в базе окажется запись вида
1 2
2 1
то твой цикл впадет в бесконечность и результат непредсказуем
0
1264 / 978 / 384
Регистрация: 02.09.2012
Сообщений: 3,021
17.06.2019, 22:26
поддержу... примеры здесь
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
17.06.2019, 22:26
Помогаю со студенческими работами здесь

ORA-32044: обнаружен цикл при выполнении рекурсивного запроса WITH
Всем привет! Работаю со схемой HR. таблицы regions и countries. inser into regions (region_id,region_name) values (2,Americas); ...

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

Расчет факториала (с использованием рекурсивного вызова подпрограммы)
Доброго времени суток! У меня вопрос как реализовать программу следующего типа: Расчет факториала (с использованием рекурсивного вызова...

Решение уравнения с использованием рекурсивного метода деления отрезка пополам
Помогите исправить код. Задание: программа, которая определяет решение уравнения f(x)=0 на заданном отрезке (a,b) с точностью E с...

Написать алгоритм рекурсивного перебора папок в многопоточности с использованием Fork/Join Framework
Написать алгоритм рекурсивного перебора папок в многопоточности с использованием Fork/Join Framework


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru