Рекурсивный запрос для сирот в неиерархической структуре - PullRequest
1 голос
/ 08 января 2020

Я пытаюсь выяснить рекурсивный запрос, но мой случай не совсем вписывается в примеры, которые я видел. Таблица является классовой c родительской / дочерней таблицей. Он имеет три поля: parent, child и fco.

create table relationships (
    fco boolean,
    parent varchar(36),
    child varchar(36)
);

Теперь сложная часть состоит в том, что это не иерархия. Любой объект может ссылаться на любой другой объект, даже сам по себе. Таким образом, данные могут быть запутаны. Поле fco указывает «объект первого класса», что означает, что на него не должен ссылаться другой объект. Цель состоит в том, чтобы написать запрос, который выбирает все записи, на которые не ссылается fco, и на которые не ссылается запись, на которую ссылается fco, et c. Я пытаюсь очистить сирот.

Я играл с рекурсивными запросами, но я просто никуда не попал. Любая помощь будет оценена.

РЕДАКТИРОВАТЬ

Вот SQL для создания полного рабочего примера. Также прилагается диаграмма структуры, которая, как вы можете видеть, довольно запутана. При рекурсивном выборе следует выбрать либо все в зеленом поле (поскольку все оно происходит от «фрукта», являющегося объектом первого класса), либо выбрать все, что не в зеленом поле.

Обратите внимание, что java ссылается на фрукты (fco), но это не должно помешать их выбору во внешней группе. Ссылка на fco не мешает узлу быть сиротой ... на него ссылаются fco делает его не сиротой.

create table relationships (
    fco boolean default 0,
    parent varchar(36),
    child varchar(36)
);

insert into relationships(fco, parent, child) values(1, 'fruit', 'green');
insert into relationships(fco, parent, child) values(1, 'fruit', 'blue');
insert into relationships(fco, parent, child) values(1, 'fruit', 'purple');
insert into relationships(parent, child) values('green', 'kiwi');
insert into relationships(parent, child) values('green', 'kiwi');
insert into relationships(parent, child) values('green', 'granny-smith');
insert into relationships(parent, child) values('blue', 'blueberry');
insert into relationships(parent, child) values('blueberry', 'blue');
insert into relationships(parent, child) values('purple', 'plum');
insert into relationships(parent, child) values('granny-smith', 'blueberry');
insert into relationships(parent, child) values('paprika', 'plum');
insert into relationships(parent, child) values('java', 'fruit');
insert into relationships(parent, child) values('pepper', 'java');
insert into relationships(parent, child) values('pepper', 'matico');
insert into relationships(parent, child) values('matico', 'matico');

enter image description here

1 Ответ

0 голосов
/ 08 января 2020

Я не уверен, что это уже работает для вашего случая, но следующий CTE выберет все в зеленом поле (ну, все , кроме родительский объект, с которого начался запрос, в настоящее время):

WITH RECURSIVE ancestor(child) AS (
  SELECT child from relationships WHERE parent = 'fruit'
  UNION
  SELECT r.child from ancestor a INNER JOIN relationships r on r.parent = a.child
)
SELECT child FROM ancestor;

Результат

green
blue
purple
granny-smith
kiwi
blueberry
plum

Игровая площадка онлайн: https://sqliteonline.com/#fiddle -5e163706674709agk55ql6e5

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...