Есть банальная таблица для хранения древовидной структуры:
CREATE TABLE test (
tid serial PRIMARY KEY,
pid INTEGER,
name VARCHAR NOT NULL
-- на самом деле тип name это домен с проверкой, но в данном случае это не важно КМК
-- да и constraint'ы опустим.
);
И есть две задачи:
- Найти запись в соответствии с заданным путём
n1.n2.n3.n4
- Найти ближайший элемент к заданному пути. Т.е. например для
n1.n2.n3.n4
вернуть запись с путёмn1.n2
т.к. уn1.n2
нет потомков.
Покопавшись с WITH RECURSIVE
для первой задачи получилось такое себе решение:
WITH RECURSIVE r1 as (
SELECT t1.tid, t1.pid, t1.name, cast( t1.name as text ) as path
FROM test t1 WHERE pid is null and t1.name = split_part('n1.n2.n3.n4', '.', 1)
UNION
SELECT t2.tid, t2.pid, t2.name, r1.path || '.'|| t2.name as path
FROM test t2
join r1 on t2.pid = r1.id
)
select * from r1 where path = 'n1.n2.n3.n4';
Хотя меня несколько напрягает сравнение строк, но я не уверен как сделать быстрее.
И по второму вопросу не могу докумекать, как всё это реализовать. Может кто-нибудь чего подскажет?