Je ne connaissais pas de fonction faisant cela prête à l'emploi dans PostgreSQL.
A CTE récursif
serait l'élément clé d'une solution plutôt élégante (disponible dans PostgreSQL 8.4 ou version ultérieure).
Je suppose une table filter
pour contenir les chaînes de filtre :
CREATE TABLE filter (f_id int, string text);
Et un tableau tbl
pour rechercher la correspondance la plus longue :
CREATE TABLE tbl(t_id int, col text);
Requête
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;
Détaillé explication du fonctionnement du SELECT final dans cette réponse connexe.
Démo de travail sur sqlfiddle.
Vous n'avez pas défini quelle correspondance choisir parmi un ensemble de correspondances de longueur égale. Je choisis un gagnant arbitraire parmi les égalités.
PostgreSQL 9.1 a introduit CTE modifiant les données , vous pouvez donc l'utiliser dans une UPDATE
déclaration directement.