我需要找到在最后一次出现以下事件模式“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
非常感谢任何帮助!
答案 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