如何在 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 中选择一个子字符串直到一个特定的字符?的主要内容,如果未能解决你的问题,请参考以下文章