1

在 PostgreSQL 中获得准确和快速查询以获得最长前缀匹配的最佳方法是什么?

是吗:

A.) select * from table where column in (subselect) ;

B.) 从 strpos(column,column2) = 1 的表中选择 *
    按长度排序(column2) desc limit 1 ;

C.) select * from table where column ~ column2
    按长度排序(column2) desc 限制 1

我打算在更新中使用。有任何想法吗?

4

1 回答 1

0

我不知道在 PostgreSQL 中有一个开箱即用的函数。递归 CTE将是一个相当优雅的解决方案的关键元素(在 PostgreSQL 8.4 或更高版本中可用)

我假设一个表格filter来保存过滤器字符串:

CREATE TABLE filter (f_id int, string text);

还有一个tbl要搜索最长匹配的表:

CREATE TABLE tbl(t_id int, col text);

询问

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;

在这个相关答案中详细解释了最终 SELECT 的工作原理。
sqlfiddle 上的工作演示。

您没有定义从一组同样长的匹配中选择哪个匹配。我正在从平局中挑选一位任意获胜者。

我打算在更新中使用。

PostgreSQL 9.1 引入了数据修改 CTE,因此您可以UPDATE直接在语句中使用它。

于 2012-06-01T16:06:17.543 回答