PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Längste Präfixübereinstimmung

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.