gpt4 book ai didi

sql - Oracle SQL : Is it possible using SUBSTR and INSTR to return ALL Strings in a given text field?

转载 作者:行者123 更新时间:2023-12-02 09:05:58 26 4
gpt4 key购买 nike

我正在处理一些存储在 VARCHAR2(4000) 列中的数据,这些数据主要是文本注释,但也包含文本中的日期。我编写了一个查询,它使用 SUBSTR 和 INSTR 进行模式匹配并查找日期之前的前导文本值,然后使用 SUBST 返回日期值,然后使用 TO_DATE 将其转换为日期。这很有效,但是我有许多记录包含多个评论,因此包含多个日期。使用上述方法我只能指定此模式的第(n)次出现,是否有一种方法可以在匹配时返回所有日期而不是仅返回一次出现?

这是 varchar 列中的数据示例;

LOCKED ENTITY: ACCOUNT
LOCKED BY USER: ops
LOCKED AT: 31/05/2004 11:47
CUST NOTES: <Please enter explanation here>
Customer notes are entered here.

UNLOCKED ENTITY: ACCOUNT
UNLOCKED BY USER: ops
UNLOCKED AT: 31/05/2004 11:49
UNLOCK NOTES: <Please enter explanation here>
Test

LOCKED ENTITY: USER
LOCKED BY USER: ops
LOCKED AT: 31/05/2004 11:50
LOCK NOTES: <Please enter explanation here>
Test

UNLOCKED ENTITY: USER
UNLOCKED BY USER: ops
UNLOCKED AT: 24/08/2009 16:47
UNLOCKED NOTES: <Please enter explanation here>

这是我正在使用的查询的简化版本(为了清楚起见,删除了所有其他不相关的联接和列);

select substr(VALUE, INSTR(VALUE,'LOCKED AT: ',1)+11, 10) as "DATE"
from tableA a
join tableB b
on a.id = b.id
where regexp_like (VALUE ,'ABC|DEF|GHI');

DATE
----------
31/05/2004

对于上述查询,我​​想返回字符串“LOCKED AT:”之后的所有日期,例如;

 DATE
----------
31/05/2004
31/05/2004

如有任何帮助,我们将不胜感激。有关数据库版本是 Oracle 10g 的信息,我尝试使用 REGEXP_COUNT 来实现我的想法,但仅适用于 11g 及以上版本。

非常感谢

最佳答案

您可以将regexp_substrconnect by level结合使用来获取所有匹配项:

提供示例数据:

WITH tableA(VALUE) AS (SELECT 'LOCKED ENTITY: ACCOUNT
LOCKED BY USER: ops
LOCKED AT: 31/05/2004 11:47
CUST NOTES: <Please enter explanation here>
Customer notes are entered here.

UNLOCKED ENTITY: ACCOUNT
UNLOCKED BY USER: ops
UNLOCKED AT: 31/05/2004 11:49
UNLOCK NOTES: <Please enter explanation here>
Test

LOCKED ENTITY: USER
LOCKED BY USER: ops
LOCKED AT: 31/05/2004 11:50
LOCK NOTES: <Please enter explanation here>
Test

UNLOCKED ENTITY: USER
UNLOCKED BY USER: ops
UNLOCKED AT: 24/08/2009 16:47
UNLOCKED NOTES: <Please enter explanation here>' FROM dual)

查询:

select ltrim( regexp_substr(VALUE,
'^LOCKED AT: ([[:digit:]]{2}/[[:digit:]]{2}/[[:digit:]]{4}\.?)',1,LEVEL,'m'),
'LOCKED AT: ') as "Dates Locked"
FROM tableA
CONNECT BY regexp_substr(VALUE,
'^LOCKED AT: ([[:digit:]]{2}/[[:digit:]]{2}/[[:digit:]]{4}\.?)',1,LEVEL,'m') IS NOT null

结果:

Dates Locked
------------
31/05/2004
31/05/2004

此查询的问题是,connect by 是针对整个表执行的 - 为了避免这种情况,一种可能的解决方案是分离这部分并独立地对任何数据行执行它:

SELECT ID, ltrim( regexp_substr(VALUE,
'^LOCKED AT: ([[:digit:]]{2}/[[:digit:]]{2}/[[:digit:]]{4}\.?)',1,lvl.column_value,'m'),
'LOCKED AT: ') as "Dates Locked"
FROM tableA
CROSS JOIN table(cast(multiset
(select level from dual
connect by regexp_substr(VALUE,
'^LOCKED AT: ([[:digit:]]{2}/[[:digit:]]{2}/[[:digit:]]{4}\.?)',1,LEVEL,'m') IS NOT null)
as sys.odcinumberlist)) lvl

关于sql - Oracle SQL : Is it possible using SUBSTR and INSTR to return ALL Strings in a given text field?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58556362/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com