1

我需要找到在以下事件模式“5065|5373|5373”最后一次出现之后出现的下一个事件。我的问题是模式可以在字符串中出现 1 到 n 次。这是我必须搜索的一些数据的示例。

BOLD中的事件是我要寻找的。

5065|5373|5373|5065|5373|5373|5065|5373|5373| 5509 |5329|5321 5065|5373|5373|5065|5373|5373| 5509 |5270|5373|5373|5373|5080|5081|5013|5040|5295|5321 5065|5373|5373| 5295 |5323|5321

任何帮助将不胜感激!

4

2 回答 2

0

一种相当直接的方法是使用递归公用表表达式 (CTE):

CREATE FUNCTION localutil.locatelastmatch(
       searchparm VARCHAR(4000), inputparm VARCHAR(4000)
)
RETURNS SMALLINT
LANGUAGE SQL
RETURN
WITH rcurs(counter, output ) AS (
    VALUES (0,0)
    UNION ALL
    SELECT counter+1, LOCATE(searchparm,inputparm,counter+1) 
       FROM rcurs
       WHERE counter < LENGTH(inputparm) AND counter < 32767
    )
SELECT MAX(output) FROM rcurs
;

它可能不是找到最后一个匹配项的最便宜的方法,但它至少是它的竞争者。通过将复杂性隐藏到标量用户定义函数 (UDF) 中,您不必将 SQL 递归引入需要搜索模式的最后一个实例的每个查询中。

以下是它对您的示例字符串的作用:

WITH originput(val) as (VALUES
('5065|5373|5373|5065|5373|5373|5065|5373|5373|5509|5329|5321'),
('5065|5373|5373|5065|5373|5373|5509|5270|5373|5373|5373|5080|5081|5013|5040|5295|5321'),
('5065|5373|5373|5295|5323|5321')
)
SELECT LENGTH(val) AS inputlength, 
    localutil.locatelastmatch( '5065|5373|5373|', val ) AS finaloffset,
    SUBSTR(val, localutil.locatelastmatch( '5065|5373|5373|', val ) 
    + LENGTH( '5065|5373|5373|' ), 4) AS nextitem
FROM originput
;

INPUTLENGTH FINALOFFSET NEXTITEM
----------- ----------- --------
         59          31 5509
         84          16 5509
         29           1 5295
于 2012-06-13T21:53:05.340 回答
0

如果您无法创建新的存储过程或 UDF,这里有一个递归查询可以帮您完成:

WITH Recurs(id, index, token, source) as (
            SELECT id, LOCATE('5065|5373|5373|', M.PATH_2), '', M.PATH_2
            FROM M
            UNION ALL 
            SELECT id, LOCATE('5065|5373|5373|', source, index + 15), 
            SUBSTR(source, index + 15, 4), source
            FROM Recurs
            WHERE index > 0)
SELECT * 
FROM Recurs
WHERE index = 0

这产生了预期的:

ID  INDEX   TOKEN  SOURCE 
3   0       5295   5065|5373|5373|5295|5323|5321     
2   0       5509   5065|5373|5373|5065|5373|5373|5509|5270|5373|5373|5373|5080|5081|5013|5040|5295|5321
1   0       5509   5065|5373|5373|5065|5373|5373|5065|5373|5373|5509|5329|5321
于 2012-06-13T22:40:28.047 回答