Estou no Postgres 15.1 e tenho uma node
tabela como segue:
CREATE TABLE node (
id TEXT PRIMARY KEY,
is_skippable BOOL,
prev TEXT REFERENCES node(id),
"next" TEXT REFERENCES node(id)
);
Esta tabela representa uma série de listas duplamente vinculadas, mas em certas ocasiões, para determinadas consultas, desejo remover is_skippable
nós da lista e vinculá-los.
Por exemplo, se eu tivesse os seguintes dados propagados no banco de dados, onde há uma lista vinculada de A1 <-> A2 <-> A3
(com A2
ignorável) e uma de B1 <-> B2
:
INSERT INTO node VALUES
('A1', FALSE, NULL, 'A2'),
('A2', TRUE, 'A1', 'A3'),
('A3', FALSE, 'A2', NULL),
('B1', FALSE, NULL, 'B2'),
('B2', FALSE, 'B1', NULL);
Para certas consultas, quero vincular is_skippable
os nós. Então, se eu consultar esta tabela completa, o conjunto de resultados que estou procurando é:
eu ia | anterior | próximo |
---|---|---|
A1 | NULO | A3 |
A3 | A1 | NULO |
B1 | NULO | B2 |
B2 | B1 | NULO |
Observe que A2
não está no conjunto de resultados e A2
os ponteiros foram reescritos no nó antes e depois dele.
Existe uma maneira bem suportada de fazer isso no Postgres? Já vi respostas para listas vinculadas simples em outros lugares do StackOverflow (como o conceito de lista vinculada em postgresql ), mas elas não implicam na necessidade de reescrever ponteiros. Obrigado!
Exemplo de violino aqui: https://dbfiddle.uk/4lB4TAtF .
Você provavelmente poderia recolhê-lo para executar uma consulta lateral em ambas as direções ao mesmo tempo, mas o fato de isso apenas tentar pular para o elemento não ignorável mais próximo pode na verdade ser uma vantagem, tornando a parte recursiva mais leve. Demonstração em db<>fiddle:
Não importa se as listas se ramificam. Você pode restringir as condições de junção cte recursivas para verificar a bidirecionalidade do link e fazê-lo seguir estritamente o caminho bidirecional:
as ramificações começam com um link unidirecional, portanto, isso irá filtrá-las.
Ele não se importa com ciclos/anéis/loops, se você tiver algum, graças à detecção de ciclo integrada .
Um índice de cobertura acelera as coisas:
Você pode estar interessado em pgrouting e Apache AGE .
aqui está uma solução usando um cte recursivo :
demonstração em dbfiddle