在PostgreSQL中获得准确快速查询以获得最长前缀匹配的最佳方法是什么?
是吗:
A.) select * from table where column in (subselect) ; B.) select * from table where strpos(column,column2) = 1 order by length(column2) desc limit 1 ; C.) select * from table where column ~ column2 order by length(column2) desc limit 1
我打算在更新中使用。有什么想法吗?
答案 0 :(得分:0)
我不知道在PostgreSQL中开箱即用的功能。
recursive 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;
Detailed explanation how the final SELECT works in this related answer.
Working demo on sqlfiddle.
您没有定义从一组同样长的匹配中选择哪个匹配。我从领带中挑选了一个任意的赢家。
我打算在更新中使用。
PostgreSQL 9.1引入了data modifying CTEs,因此您可以直接在UPDATE
语句中使用它。