【问题标题】:Oracle SQL getting the nth element regexpOracle SQL 获取第 n 个元素正则表达式
【发布时间】:2011-11-13 20:21:48
【问题描述】:

我正在尝试使用 Oracle 中的 SQL 获取逗号分隔字符串中的第 n 个元素。

到目前为止,我有以下..

SELECT regexp_substr(
   '100016154,5101884LT00001,,,,,100000010892100000012655,L,SEI,5101884LT00001,1,SL,3595.03,00,2,N,N,G,N',
   '[^,]+',
   1,
   7)
FROM dual;

但是当元素为空时它不起作用,即,有人可以帮忙吗?

【问题讨论】:

  • 当您在 RDBMS 中看到 CSV 或其他序列化值时,您就知道有些不对劲。
  • @NullUserException,好点。不幸的是,我遇到过太多次了:-(

标签: sql regex oracle denormalized


【解决方案1】:

如果您的分隔值始终是逗号之间的字母数字,那么您可以尝试:

SELECT REGEXP_SUBSTR( <delimied_string>, '[[:alnum:]]{0,},', 1, 7 )
  FROM dual;

获取第七个值(包括结尾的逗号)。如果它是空的,你只会得到尾随的逗号(你可以很容易地删除它)。

显然,如果您想要除第七个以外的值,则将第四个参数值更改为您想要的任何第 n 个出现,例如

SELECT REGEXP_SUBSTR( <delimied_string>, '[[:alnum:]]{0,},', 1, <nth occurance> )
  FROM dual;

编辑:因为我喜欢 REGEX,这里有一个解决方案,它也删除了尾随逗号

SELECT REPLACE(
          REGEXP_SUBSTR(<delimied_string>, '[[:alnum:]]{0,},', 1, <nth>), 
          ','
       )
  FROM dual;

希望对你有帮助

【讨论】:

  • 你好奥利,我有同样的问题,但你的建议对我的情况不起作用。我需要从字符串 select regexp_substr('SENDER ,3B13 ,3 ,300 , , , , , ,', '[[:alnum:]]{0,},', 1, 2) from dual; 中获取第三个值,但我只得到 , 字符串。你能告诉我我做错了什么吗?
【解决方案2】:

你可以用一个小技巧来做到这一点:首先用逗号后跟一个空格替换所有逗号,然后跳过那个额外的前导空格:

SQL> with data as
  2  ( select '100016154,5101884LT00001,,,,,100000010892100000012655,L,SEI,5101884LT00001,1,SL,3595.03,00,2,N,N,G,N' txt
  3      from dual
  4  )
  5  select regexp_substr(txt,'[^,]+',1,7)                             seventh_element_wrong
  6       , replace(txt,',',', ')                                      with_extra_space_after_comma
  7       , regexp_substr(replace(txt,',',', '),'[^,]+',1,7)           seventh_element_leading_space
  8       , substr(regexp_substr(replace(txt,',',', '),'[^,]+',1,7),2) the_seventh_element
  9    from data
 10  /

S WITH_EXTRA_SPACE_AFTER_COMMA
- ----------------------------------------------------------------------------------------------------------------------
SEVENTH_ELEMENT_LEADING_S THE_SEVENTH_ELEMENT
------------------------- ------------------------
1 100016154, 5101884LT00001, , , , , 100000010892100000012655, L, SEI, 5101884LT00001, 1, SL, 3595.03, 00, 2, N, N, G, N
 100000010892100000012655 100000010892100000012655

问候,
抢。

【讨论】:

    【解决方案3】:

    除非你被正则表达式困住,否则这也可以:

    WITH q AS (
    SELECT '100016154,5101884LT00001,,,,,100000010892100000012655,L,SEI,5101884LT00001,1,SL,3595.03,00,2,N,N,G,N' thestring FROM dual
    )
    SELECT SUBSTR(thestring, INSTR(thestring,',',1,6)+1, 
                             INSTR(thestring,',',1,7)-INSTR(thestring,',',1,6)-1) "The Element"
      FROM q;
    
    The Element
    ------------------------
    100000010892100000012655
    

    另一种可能性。您尚未指定数据的来源。您是否可以使用外部表来读取您的输入源并通过 SQL 处理它?

    【讨论】:

    • 在语句中调用 INSTR 三次而不是只调用一次 REGEXP_SUBSTR 会有开销吗? (我意识到分隔字符串的长度尚未指定,这将是一个因素)。
    • @Ollie,它可能,只有通过测量结果才能确定。 REGEXP_* 函数并非没有自己的开销问题。
    【解决方案4】:
    SELECT rtrim(regexp_substr('100016154,5101884LT00001,,,,,100000010892100000012655,L,SEI,5101884LT00001,1,SL,3595.03,00,2,N,N,G,N','[^,]{0,}[,]?',1,7),',')
    FROM dual;
    

    【讨论】:

      猜你喜欢
      • 2021-09-03
      • 1970-01-01
      • 1970-01-01
      • 2014-06-26
      • 2021-05-22
      • 1970-01-01
      • 1970-01-01
      • 2013-12-20
      相关资源
      最近更新 更多