2

没有两个相邻字符(从 a 到 z)应该是相同的情况;我需要更改helloworldHeLlOwOrLd,并使用如下查询:

SELECT listagg(jumping_char,'') WITHIN GROUP(ORDER BY rn) jumped_word
FROM
     (SELECT rn,
          CASE
               WHEN mod(rn, 2) = 1
               THEN upper(split_word)
               ELSE lower(split_word)
          END jumping_char
     FROM
          (SELECT regexp_substr('helloworld','.',LEVEL)split_word,
               ROWNUM rn
          FROM dual
               CONNECT BY LEVEL <= LENGTH('helloworld')
          )
     );

现在我得到了一个hello2world应该变成的字符串HeLlO2wOrLd。任何简单的,不同的查询表示赞赏并提前感谢。

4

1 回答 1

0

如果我理解正确,您想“跳过”输入中的非字符。您可以通过在旧解决方案中使用带有 rn 偏移量的 regexp_count()(而不是简单地使用 rn)来实现这一点:

SELECT listagg(jumping_char,'') WITHIN GROUP(ORDER BY rn) jumped_word
FROM
     (SELECT rn,
          CASE
               when mod (regexp_count('hello2world', '[a-zA-Z]', rn), 2) = 1
               THEN upper(split_word)
               ELSE lower(split_word)
          END jumping_char
     FROM
          (SELECT regexp_substr('hello2world','.',LEVEL)split_word,
               ROWNUM rn
          FROM dual
               CONNECT BY LEVEL <= LENGTH('hello2world')
          )
     );

更新:

为了完整起见,这是使用 MODEL 子句的替代解决方案:

with t as 
  (select 'hello2world' txt from dual)
select listagg(case 
                 when mod(v2.char_cnt, 2) = 1 
                 then upper(v2.txt) 
                 else lower(v2.txt) 
               end, 
               '') within group(order by v2.rn)
from (
  select 
    v1.txt, 
    rownum as rn, 
    sum(case 
          when regexp_like(txt, '[a-zA-Z]') 
          then 1 
          else 0 
        end) over (partition by 1 order by rownum) as char_cnt
  from (
    SELECT TXT   
    FROM T
    MODEL
      RETURN UPDATED ROWS
      PARTITION BY(ROWNUM RN)
      DIMENSION BY (0 POSITION)
      MEASURES     (TXT ,length(txt) NB_MOT)
      RULES 
        (TXT[FOR POSITION FROM  1 TO NB_MOT[0] INCREMENT 1] = 
          substr(txt[0], CV(POSITION), 1)  )
   ) v1      
) v2
于 2013-09-27T11:19:09.257 回答