Mir wäre keine Funktion bekannt, die dies standardmäßig in PostgreSQL macht.
Ein rekursiver CTE
wäre das Schlüsselelement für eine ziemlich elegante Lösung (verfügbar in PostgreSQL 8.4 oder höher).
Ich gehe von einem Tabellen-filter
aus um die Filterstrings zu halten:
CREATE TABLE filter (f_id int, string text);
Und eine Tabelle tbl
um nach der längsten Übereinstimmung zu suchen:
CREATE TABLE tbl(t_id int, col text);
Abfrage
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;
Detailliert Erklärung, wie das letzte SELECT in dieser verwandten Antwort funktioniert.
Funktionierende Demo auf sqlfiddle.
Sie haben nicht definiert, welche Übereinstimmung aus einer Reihe gleich langer Übereinstimmungen ausgewählt werden soll. Ich wähle einen beliebigen Gewinner aus Gleichständen aus.
PostgreSQL 9.1 führte Daten ändernde CTEs , sodass Sie dies in einem UPDATE
verwenden können Anweisung direkt.