Транзитивное замыкание в SQL

Последнее время мне часто приходится заниматься обработкой данных, для этого я, в основном, использую замечательную БД PostgreSQL. Хочу поделиться решением одной из проблем, c которой мне недавно пришлось столкнуться — нахождение транзитивного замыкания некоторого отношения.

Допустим у нас есть следующая табличка

postgres=# table rel;
 a | b 
---+---
 1 | 2
 2 | 3
(2 rows)

и мы хотим получить её транзитивное замыкание, то есть добавить строчку (1, 3). Для этого в SQL2003 существует recursive common table expressions, вот как это можно сделать с их помощью:

postgres=# with recursive c as (
  select * from rel 
    union 
  select rel.a, c.b from rel join c on rel.b = c.a) table c;
 a | b 
---+---
 1 | 2
 2 | 3
 1 | 3
(3 rows)

просто и со вкусом!