如何选择包含特定子字符串的单词列表作为 SQL 查询(oracle)的一部分?
Posted
技术标签:
【中文标题】如何选择包含特定子字符串的单词列表作为 SQL 查询(oracle)的一部分?【英文标题】:How to select the list of words containing a particular substring as part of a SQL query (oracle)? 【发布时间】:2019-12-13 19:54:05 【问题描述】:我正在尝试返回包含字符串中某个子字符串的“单词”列表(以空格分隔),作为 Oracle Sql 查询的一部分。想要以逗号分隔列表的形式返回结果。每个匹配的单独行也可以。
[text_col] 字段中的示例字符串:
一些词 123-asdf-789A 和这个 456-asdf-555A 更多的词等等。
想要的结果:123-asdf-789A, 456-asdf-555A
这是我目前所拥有的,但它只返回第一个结果,而且它是两个单独的正则表达式这一事实使得我很难像我想要的那样连接所有匹配项。
CONCAT(REGEXP_SUBSTR(text_col, ''(([^[:space:]]+)\asdf)'', 1, 1, ''i'', 1),
REGEXP_SUBSTR(text_col, ''\asdf([^[:space:]]+)'', 1, 1, ''i'', 1))
【问题讨论】:
【参考方案1】:您可以将一些正则表达式函数一起使用:
with tab(str) as
(
select 'some words 123-asdf-789A and also this one 456-asdf-555A more words etc' from dual
), t as
(
select regexp_substr(str,'[^[:space:]]+',1,level) as str, level as lvl
from tab
connect by level <= regexp_count(str,'[:space:]')
)
select listagg(str,',') within group (order by lvl) as "Result"
from t
where regexp_like(str,'-');
Result
---------------------------------
123-asdf-789A,456-asdf-555A
Demo
首先用空格分割(通过[:space:]
posix)并取出包含破折号的字符,最后通过listagg()
函数连接
【讨论】:
【参考方案2】:使用递归子查询因式分解子句并遍历连接字符串的所有匹配项:
Oracle 设置:
CREATE TABLE test_data ( value ) AS
SELECT 'some words 123-asdf-789A and also this one 456-asdf-555A more words etc.' FROM DUAL UNION ALL
SELECT 'some words without the expected sub-string' FROM DUAL UNION ALL
SELECT 'asdf asdf-123 456-asdf 78-asdf-90' FROM DUAL
查询:
WITH matches ( value, idx, cnt, match ) AS (
SELECT value,
0,
REGEXP_COUNT( value, '\S*asdf\S*' ),
CAST( NULL AS VARCHAR2(4000) )
FROM test_data
UNION ALL
SELECT value,
idx + 1,
cnt,
CASE idx WHEN 0 THEN '' ELSE match || ' ' END
|| REGEXP_SUBSTR( value, '\S*asdf\S*', 1, idx + 1 )
FROM matches
WHERE idx < cnt
)
SELECT value, match
FROM matches
WHERE idx = cnt;
输出:
价值 |匹配 :------------------------------------------------- ---------------------- | :-------------------------------- 一些没有预期子字符串的单词 | 空 一些单词 123-asdf-789A 和这个 456-asdf-555A 更多的单词等等。 123-asdf-789A 456-asdf-555A asdf asdf-123 456-asdf 78-asdf-90 | asdf asdf-123 456-asdf 78-asdf-90
db小提琴here
【讨论】:
以上是关于如何选择包含特定子字符串的单词列表作为 SQL 查询(oracle)的一部分?的主要内容,如果未能解决你的问题,请参考以下文章
一道Python练习题引发的,一个知识点的探讨:删除列表中特定元素的几种方法