Eu não saberia de uma função fazendo isso fora da caixa no PostgreSQL.
A CTE recursiva seria o elemento chave para uma solução bastante elegante (disponível no PostgreSQL 8.4 ou posterior).
Estou assumindo uma tabela
filter
para manter as strings de filtro:CREATE TABLE filter (f_id int, string text);
E uma tabela
tbl
para procurar a correspondência mais longa:CREATE TABLE tbl(t_id int, col text);
Consulta
WITH RECURSIVE
f AS (SELECT f_id, string, length(string) AS flen FROM filter)
,t AS (SELECT t_id, col, length(col) AS tlen FROM tbl)
,x AS (
SELECT t.t_id, f.f_id, t.col, f.string
,2 AS match, LEAST(flen, tlen) AS len
FROM t
JOIN f ON left(t.col, 1) = left(f.string, 1)
UNION ALL
SELECT t_id, f_id, col, string, match + 1, len
FROM x
WHERE left(col, match) = left(string, match)
AND match <= len
)
SELECT DISTINCT
f_id
,string
,first_value(col) OVER w AS col
,first_value(t_id) OVER w AS t_id
,(first_value(match) OVER w -1) AS longest_match
FROM x
WINDOW w AS (PARTITION BY f_id ORDER BY match DESC)
ORDER BY 2,1,3,4;
Detalhado explicação de como o SELECT final funciona nesta resposta relacionada.
Demonstração de trabalho no sqlfiddle.
Você não definiu qual correspondência escolher em um conjunto de correspondências igualmente longas. Estou escolhendo um vencedor arbitrário de empates.
O PostgreSQL 9.1 introduziu CTEs de modificação de dados , então você pode usar isso em um
UPDATE
declaração diretamente.