Есть банальная таблица для хранения древовидной структуры:
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';
Хотя меня несколько напрягает сравнение строк, но я не уверен как сделать быстрее.
И по второму вопросу не могу докумекать, как всё это реализовать. Может кто-нибудь чего подскажет?

