如何在字符模式结束后搜索字符串以查找数据(SQL DB2)

时间:2012-06-13 14:54:48

标签: sql db2

我需要找到在最后一次出现以下事件模式“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

非常感谢任何帮助!

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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