これらの各クエリは、テーブル全体だけでなく、単一の ID に対しても機能します。
また、パス/フルパスまたは他のすべての列のみを返すこともできます。
SELECT t.*, concat_ws('->', t1.path, t.name) AS full_path
FROM tbl t
LEFT JOIN LATERAL (
SELECT string_agg(t1.name, '->' ORDER BY i) AS path
FROM generate_subscripts(t.arrayofparents, 1) i
JOIN tbl t1 ON t1.id = t.arrayofparents[i]
) t1 ON true
WHERE t.id = 4; -- optional
または、サブクエリに移動することもできますORDER BY
- 少し速いかもしれません:
SELECT concat_ws('->', t1.path, t.name) AS full_path
FROM tbl t, LATERAL (
SELECT string_agg(t1.name, '->') AS path
FROM (
SELECT t1.name
FROM generate_subscripts(t.arrayofparents, 1) i
JOIN tbl t1 ON t1.id = t.arrayofparents[i]
ORDER BY i
) t1
) t1
WHERE t.id = 4; -- optional
集計はサブクエリで行われるため、外側のクエリにステップLATERAL
は必要ありません。GROUP BY
サブクエリは集計関数により常に行を返すため、NULL または空のLEFT JOIN LATERAL ... ON true
すべての行を保持する必要もありません。Postgres 9.3が必要です。arrayofparents
LATERAL
LATERAL
concat_ws()
連結で可能な NULL 値を無視するために使用します。
SQL フィドル。
WITH OTDINALITY
Postgres 9.4では少しシンプルで高速になります:
SELECT t.*, concat_ws('->', t1.path, t.name) AS full_path
FROM tbl t, LATERAL (
SELECT string_agg(t1.name, '->' ORDER BY ord) AS path
FROM unnest(t.arrayofparents) WITH ORDINALITY a(id,ord)
JOIN tbl t1 USING (id)
) t1
WHERE t.id = 4;
詳細な説明:
UNION ALL
pg 9.3 のバリアント
SELECT t1.full_path
FROM tbl t, LATERAL (
SELECT string_agg(name, '->') AS full_path
FROM (
(
SELECT name
FROM generate_subscripts(t.arrayofparents, 1) i
JOIN tbl ON id = t.arrayofparents[i]
ORDER BY i
)
UNION ALL SELECT t.name
) t1
) t1
WHERE t.id = 4;