第一个例子没有递归,只应用匹配字符串的模式(假设只有一个模式会匹配):
-
list 只是提供替换列表的一种方式。
-
args 提供了一个字符串来应用替换。
-
doit 是仅应用来自 list 的匹配模式的逻辑
- 最终的查询表达式会显示匹配案例的结果。
WITH list (id, arg1, arg2) AS (
SELECT 1, 'c1', 'x' UNION
SELECT 2, 'd1', 'x' UNION
SELECT 3, 'e1', 'x' UNION
SELECT 4, 'f1', 'x' UNION
SELECT 5, 'g1', 'x' UNION
SELECT 6, 'h1', 'x'
)
, args (start_str) AS (
SELECT 'abcde1fghijklmnop'
)
, doit (str) AS (
SELECT regexp_replace(start_str, arg1, arg2)
FROM args
JOIN list
ON regexp_like(args.start_str, list.arg1)
)
SELECT * FROM doit
;
结果:
+------------------+
| str |
+------------------+
| abcdxfghijklmnop |
+------------------+
1 row in set
如果您有支持 WITH RECURSIVE 的 presto 版本(如 trino),这里有一个示例,说明如何使用递归来应用具有可变数量替换的替换列表。
-
list 只是提供替换列表的一种方式。
-
args 提供了一个字符串来应用替换。
-
doit 是迭代 list 的递归逻辑
- 最终查询表达式显示所有结果(0、1 到 n)。
WITH RECURSIVE list (id, arg1, arg2) AS (
SELECT 1, 'c', 'x' UNION
SELECT 2, 'd', 'x' UNION
SELECT 3, 'e', 'x' UNION
SELECT 4, 'f', 'x' UNION
SELECT 5, 'g', 'x' UNION
SELECT 6, 'h', 'x'
)
, args (start_str) AS (
SELECT 'abcdefghijklmnop'
)
, doit (n, str) AS (
SELECT 0 , start_str FROM args UNION ALL
SELECT n+1, regexp_replace(str, arg1, arg2)
FROM doit
JOIN list
ON list.id = n+1
)
SELECT * FROM doit
ORDER BY n
;
结果:
+------+------------------+
| n | str |
+------+------------------+
| 0 | abcdefghijklmnop |
| 1 | abxdefghijklmnop |
| 2 | abxxefghijklmnop |
| 3 | abxxxfghijklmnop |
| 4 | abxxxxghijklmnop |
| 5 | abxxxxxhijklmnop |
| 6 | abxxxxxxijklmnop |
+------+------------------+
7 rows in set
与上一步调整相同的 SQL:
- 最终的查询表达式只获取被替换字符串的最后一个版本。
WITH RECURSIVE list (id, arg1, arg2) AS (
SELECT 1, 'c', 'x' UNION
SELECT 2, 'd', 'x' UNION
SELECT 3, 'e', 'x' UNION
SELECT 4, 'f', 'x' UNION
SELECT 5, 'g', 'x' UNION
SELECT 6, 'h', 'x'
)
, args (start_str) AS (
SELECT 'abcdefghijklmnop'
)
, doit (n, str) AS (
SELECT 0 , start_str FROM args UNION ALL
SELECT n+1, regexp_replace(str, arg1, arg2)
FROM doit
JOIN list
ON list.id = n+1
)
SELECT * FROM doit
ORDER BY n DESC
LIMIT 1
;
结果:
+------+------------------+
| n | str |
+------+------------------+
| 6 | abxxxxxxijklmnop |
+------+------------------+
1 row in set