Jag skulle inte känna till en funktion som gör detta direkt i PostgreSQL.
En rekursiv CTE
skulle vara nyckelelementet för en ganska elegant lösning (tillgänglig i PostgreSQL 8.4 eller senare).
Jag antar ett tabell filter
för att hålla filtersträngarna:
CREATE TABLE filter (f_id int, string text);
Och en tabell tbl
för att söka efter den längsta matchningen:
CREATE TABLE tbl(t_id int, col text);
Fråga
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;
Detaljerad förklaring hur den slutliga SELECT fungerar i detta relaterade svar.
Fungerande demo på sqlfiddle.
Du har inte definierat vilken match du ska välja från en uppsättning lika långa matcher. Jag väljer en godtycklig vinnare från oavgjort.
PostgreSQL 9.1 introducerade datamodifierande CTE:er , så du kan använda detta i en UPDATE
uttalande direkt.