我正在使用查询来获取不同的行而不是分号分隔的值。
该表如下所示:
row_id aggregator
1 12;45
2 25
Run Code Online (Sandbox Code Playgroud)
使用查询我希望输出如下所示:
row_id aggregator
1 12
1 45
2 25
Run Code Online (Sandbox Code Playgroud)
我正在使用以下查询:
SELECT
DISTINCT ROW_ID,
REGEXP_SUBSTR(AGGREGATOR,'[^;]+',1,LEVEL) as AGGREGATOR
FROM DUMMY_1
CONNECT BY REGEXP_SUBSTR(AGGREGATOR,'[^;]+',1,LEVEL) IS NOT NULL;
Run Code Online (Sandbox Code Playgroud)
即使对于 300 条记录,它也非常慢,而且我必须处理 40000 条记录。
众所周知,正则表达式是昂贵的函数,因此当性能至关重要时(例如在子句中使用标准函数CONNECT BY),您应该尽量减少它们的使用。
使用标准函数(INSTR、SUBSTR、REPLACE)会更高效,但生成的代码将难以阅读/理解/维护。
我无法抗拒写一个递归 QTE,它比正则表达式和标准函数都高效得多。此外,递归 QTE 查询可以说具有一定的优雅性。您需要 Oracle 11.2:
WITH rec_sql(row_id, aggregator, lvl, tail) AS (
SELECT row_id,
nvl(substr(aggregator, 1, instr(aggregator, ';') - 1),
aggregator),
1 lvl,
CASE WHEN instr(aggregator, ';') > 0 THEN
substr(aggregator, instr(aggregator, ';') + 1)
END tail
FROM dummy_1 initialization
UNION ALL
SELECT r.row_id,
nvl(substr(tail, 1, instr(tail, ';') - 1), tail),
lvl + 1,
CASE WHEN instr(tail, ';') > 0 THEN
substr(tail, instr(tail, ';') + 1)
END tail
FROM rec_sql r
WHERE r.tail IS NOT NULL
)
SELECT * FROM rec_sql;
Run Code Online (Sandbox Code Playgroud)
您可以在SQLFiddle上看到该解决方案性能非常好,与@ABCade 的解决方案相当。(感谢 ABCade 提供的测试用例)。