【问题标题】:How to Select a substring in Oracle SQL up to a specific character?如何在 Oracle SQL 中选择一个子字符串直到一个特定的字符?
【发布时间】: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

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

【问题讨论】:

    标签: sql oracle substring trim


    【解决方案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
      

      参考:

      附录

      如果使用 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 倍。这个问题在stackoverflow.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
              

              【讨论】:

                猜你喜欢
                • 2020-05-12
                • 1970-01-01
                • 2015-01-20
                • 2020-12-30
                • 1970-01-01
                • 2018-03-14
                • 2018-10-25
                • 1970-01-01
                • 2020-02-02
                相关资源
                最近更新 更多