Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Изъять дубли из дерева / 8 сообщений из 8, страница 1 из 1
22.11.2016, 10:51
    #39351656
Kirill Razuvaev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Изъять дубли из дерева
Добрый день!
Есть две таблицы:
Код: sql
1.
2.
3.
4.
create table SUBJECTS (
MASTER_ID integer not null,
SUBJECT_ID integer not null,
primary key (MASTER_ID, SUBJECT_ID));

и
Код: sql
1.
2.
3.
4.
create table TREE(
SUBJECT_A_ID integer not null,
SUBJECT_B_ID integer not null,
primary key(SUBJECT_A_ID, SUBJECT_B_ID));

Задача, в общем-то, проста: нужно вытащить иерархию подчиненных ID для конкретного MASTER_ID. В общем случае решается через ХП и рекурсию. Но есть один нюанс: данные заполнены так, что один и тот же SUBJECT_ID может присутствовать и в таблице SUBJECTS, и в таблице TREE в виде SUBJECT_B_ID, SUBJECT_A_ID для которого также содержится в SUBJECTS. Пример:
Код: sql
1.
2.
3.
4.
5.
6.
insert into subjects(master_id, subject_id) values(999, 1);
insert into subjects(master_id, subject_id) values(999, 1);
insert into subjects(master_id, subject_id) values(999, 3); --   <<-
insert into tree(subject_a_id, subject_b_id) values(1,2);
insert into tree(subject_a_id, subject_b_id) values(2,3); -- <<--
insert into tree(subject_a_id, subject_b_id) values(3,4);

В простом варианте получаем ветви 1-2-3-4 и 3-4. Задача состоит в том, чтобы не дублировать то, что уже вошло как фрагмент, т.е. показать только ветвь 1-2-3-4. Формализуя задачу, получается, что нужно убрать те узлы верхнего уровня, которые уже входят в дерево, как узлы более низких уровней. В рамках рекурсивной ХП сделать этого без промежуточной таблицы не получается, поскольку дерево еще не собрано, да и фрагмент может быть сформирован раньше, чем полная ветвь. Быть может, есть другой подход?
...
Рейтинг: 0 / 0
22.11.2016, 11:23
    #39351681
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Изъять дубли из дерева
Kirill RazuvaevБыть может, есть другой подход?
Либо временная таблица, либо проверка на лету снизу вверх.
Второе с нужными индексами не сильно напряжет субд.
...
Рейтинг: 0 / 0
22.11.2016, 11:49
    #39351708
Kirill Razuvaev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Изъять дубли из дерева
wadmanлибо проверка на лету снизу вверх
Пока не могу придумать, как именно проверять внутри рекурсии. Или накладывать его уже после нее?
Просто так убирать третью строку в тестовом наборе при наличии пятой - неверно, поскольку возможен вариант, что ветвь, к которой относится эта часть, не адресуется выше к нужному master_id.
...
Рейтинг: 0 / 0
22.11.2016, 11:55
    #39351715
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Изъять дубли из дерева
Kirill RazuvaevПока не могу придумать, как именно проверять внутри рекурсии.
Обратная рекурсия: 3-2-1
...
Рейтинг: 0 / 0
22.11.2016, 12:20
    #39351746
Kirill Razuvaev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Изъять дубли из дерева
wadmanОбратная рекурсия: 3-2-1Получается, это нужно делать после формирования дерева и за один проход по набору этого не сделать, т.е. опять к временной таблице приезжаем... Получается, нужно изъять, все записи с ID=N с уровнем вложенности меньшим максимального имеющегося для ID=N.
...
Рейтинг: 0 / 0
22.11.2016, 16:35
    #39352025
Kirill Razuvaev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Изъять дубли из дерева
wadmanОбратная рекурсия: 3-2-1Только вот как это реализовать?
...
Рейтинг: 0 / 0
22.11.2016, 17:32
    #39352089
KreatorXXI
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Изъять дубли из дерева
Kirill RazuvaevwadmanОбратная рекурсия: 3-2-1Только вот как это реализовать?

Посмотрите UNION DISTINCT. Можно сначала отобрать уникальные пары, а потом выложить в дерево. Ну или ещё подумать.
...
Рейтинг: 0 / 0
22.11.2016, 18:43
    #39352153
Kirill Razuvaev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Изъять дубли из дерева
KreatorXXIПосмотрите UNION DISTINCTПока не могу формализовать. Подозреваю, что конструкция with recursive могла бы быть к месту, но я в них, увы, не силен.
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Изъять дубли из дерева / 8 сообщений из 8, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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