如何在 Oracle SQL 中选择一个子字符串直到一个特定的字符?

Posted

技术标签:

【中文标题】如何在 Oracle SQL 中选择一个子字符串直到一个特定的字符?【英文标题】:How to Select a substring in Oracle SQL up to a specific character? 【发布时间】:2011-05-22 08:00:20 【问题描述】:

假设我有一个表格列,其结果如下:

ABC_blahblahblah
DEFGH_moreblahblahblah
IJKLMNOP_moremoremoremore

我希望能够编写一个从所述表中选择该列的查询,但只返回子字符串直到下划线 (_) 字符。例如:

ABC
DEFGH
IJKLMNOP

SUBSTRING 函数似乎无法胜任这项任务,因为它是基于位置的,并且下划线的位置各不相同。

我想到了TRIM函数(具体是RTRIM函数):

SELECT RTRIM('listofchars' FROM somecolumn) 
FROM sometable

但我不确定如何让它工作,因为它似乎只删除了某个字符列表/一组字符,而我真的只在导致下划线字符的字符之后。

【问题讨论】:

【参考方案1】:

您需要获取第一个下划线的位置(使用 INSTR),然后使用 substr 获取字符串从第一个字符到 (pos-1) 的部分。

  1  select 'ABC_blahblahblah' test_string,
  2         instr('ABC_blahblahblah','_',1,1) position_underscore,
  3         substr('ABC_blahblahblah',1,instr('ABC_blahblahblah','_',1,1)-1) result
  4*   from dual
SQL> /

TEST_STRING      POSITION_UNDERSCORE RES
---------------- ------------------  ---
ABC_blahblahblah                  4  ABC

Instr documentation

Susbtr Documentation

【讨论】:

【参考方案2】:

使用 SUBSTR、INSTR 和 NVL 的组合(对于没有下划线的字符串)将返回您想要的:

SELECT NVL(SUBSTR('ABC_blah', 0, INSTR('ABC_blah', '_')-1), 'ABC_blah') AS output
  FROM DUAL

结果:

output
------
ABC

用途:

SELECT NVL(SUBSTR(t.column, 0, INSTR(t.column, '_')-1), t.column) AS output
  FROM YOUR_TABLE t

参考:

SUBSTR INSTR

附录

如果使用 Oracle10g+,您可以通过REGEXP_SUBSTR 使用正则表达式。

【讨论】:

谢谢。十分优雅! (也很高兴了解 REGEXP_SUBSTR。)我什至没有想过要在 Oracle 中寻找正则表达式支持。 在 Oracle 中,您可以创建函数(独立或在包中)并在 select 语句中使用它们。 如果针对不包含您要查找的子字符串的值运行失败。如果您有INSTR('ABC/D', '_')instr 返回 0。最后你有一个从 0 到 (0-1) 的子字符串,它是空的。不好。 @MarcelStör 你可以用 T.COLUMN || '_' 所以,你的字符串中总会有一个下划线。【参考方案3】:

另一种可能性是使用REGEXP_SUBSTR.

【讨论】:

【参考方案4】:

这可以使用 REGEXP_SUBSTR 轻松完成。

请使用

REGEXP_SUBSTR('STRING_EXAMPLE','[^_]+',1,1) 

STRING_EXAMPLE 是你的字符串。

试试:

SELECT 
REGEXP_SUBSTR('STRING_EXAMPLE','[^_]+',1,1) 
from dual

它会解决你的问题。

【讨论】:

我赞成 OP 选择的解决方案,因为它确实有用。然而值得注意的是,这种解决方案比@OMG Ponies 的解决方案慢得多,尤其是在 where 条件下使用时。我的测试显示相同查询的执行速度慢了大约 6 倍。这个问题在***.com/questions/41156391/…这个话题上更进一步 在我的测试中,INSTR 解决方案的执行速度与REGEXP 解决方案几乎相同。【参考方案5】:
SELECT REGEXP_SUBSTR('STRING_EXAMPLE','[^_]+',1,1)  from dual

是正确的答案,由 user1717270 发布

如果你使用INSTR,它会给你一个假设它包含“_”的字符串的位置。如果没有怎么办?那么答案将是 0。因此,当您要打印字符串时,它将打印NULL。 示例:如果要从“host.domain”中删除域。在某些情况下,您只会有简称,即“主机”。您很可能想打印“主机”。好吧,使用INSTR,它会给你一个NULL,因为它没有找到任何“.”,即它会从0打印到0。使用REGEXP_SUBSTR,你将在所有情况下得到正确的答案:

SELECT REGEXP_SUBSTR('HOST.DOMAIN','[^.]+',1,1)  from dual;

主机

SELECT REGEXP_SUBSTR('HOST','[^.]+',1,1)  from dual;

主机

【讨论】:

【参考方案6】:

如果列中的所有字符串都没有下划线,请记住这一点 (...或者如果 null 值将是输出):

SELECT COALESCE
(SUBSTR("STRING_COLUMN" , 0, INSTR("STRING_COLUMN", '_')-1), 
"STRING_COLUMN") 
AS OUTPUT FROM DUAL

【讨论】:

【参考方案7】:

从大字符串中查找任何子字符串:

string_value:=('This is String,Please search string 'Ple');

然后从String_value中找到字符串'Ple',我们可以这样做:

select substr(string_value,instr(string_value,'Ple'),length('Ple')) from dual;

你会发现结果:Ple

【讨论】:

【参考方案8】:

如果字符串位置不固定,那么通过下面的 Select 语句我们可以得到预期的输出。

Table      Structure
ID         VARCHAR2(100 BYTE)
CLIENT     VARCHAR2(4000 BYTE)

数据-

ID    CLIENT      
1001  "clientId":"con-bjp","clientName":"ABC","providerId":"SBS"  
1002 

--

"IdType":"AccountNo","Id":"XXXXXXXX3521","ToPricingId":"XXXXXXXX3521","clientId":"Test-Cust","clientName":"MFX"

要求 - 在CLIENT 列中搜索ClientId 字符串并返回相应的值。喜欢来自"clientId":"con-bjp" --> con-bjp(Expected output)

select CLIENT,substr(substr(CLIENT,instr(CLIENT,'"clientId":"')+length('"clientId":"')),1,instr(substr(CLIENT,instr(CLIENT,'"clientId":"')+length('"clientId":"')),'"',1 )-1) cut_str from TEST_SC;

--

CLIENT                                                        cut_str 
-----------------------------------------------------------   ----------
"clientId":"con-bjp","clientName":"ABC","providerId":"SBS"    con-bjp
"IdType":"AccountNo","Id":"XXXXXXXX3521","ToPricingId":"XXXXXXXX3521","clientId":"Test-Cust","clientName":"MFX"   Test-Cust

【讨论】:

以上是关于如何在 Oracle SQL 中选择一个子字符串直到一个特定的字符?的主要内容,如果未能解决你的问题,请参考以下文章

如何从Oracle中的另一个子查询中选择具有最大列的行

Oracle Sql:如何在 sql 中添加多个子总计?

Oracle11g与PL/SQL的安装与配置(单机学习简易版)

如何在 Pl/SQL 中编写正则表达式匹配模式?

sql [sql]从连接表中选择一个子行

oracle PL/SQL解析xml