sql >> Databáze >  >> RDS >> PostgreSQL

Nejdelší shoda předpony

Nevěděl bych o funkci, která by to dělala v PostgreSQL.
A rekurzivní CTE by byl klíčovým prvkem pro poměrně elegantní řešení (dostupné v PostgreSQL 8.4 nebo novějším).

Předpokládám tabulku filter pro uložení řetězců filtru:

CREATE TABLE filter (f_id int, string text);

A tabulka tbl hledat nejdelší shodu:

CREATE TABLE tbl(t_id int, col text);

Dotaz

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;

Podrobnosti vysvětlení, jak funguje konečný SELECT v této související odpovědi.
Pracovní ukázka na sqlfiddle.

Nedefinovali jste, který zápas vybrat ze sady stejně dlouhých zápasů. Vybírám jednoho libovolného vítěze z remíz.

PostgreSQL 9.1 představil data upravující CTE , takže to můžete použít v UPDATE přímo.




  1. PHP vazba 'bigint' datový typ (připravený příkaz MySQLi)

  2. PHP/MySQL:Jak vytvořit sekci komentářů na vašem webu

  3. Načítání CSV souborů do MySQL Workbench

  4. Přístup odepřen pro uživatele 'root'@'localhost' (pomocí hesla:YES )