2015-05-29 55 views
1

假設我有字符串提取詞語的預言

Str = 'Aaa,Bbb,Abb,Ccc' 

我想把上述STR兩個部分分開如下

Str1 = 'Aaa,Abb' 

Str2 = 'Bbb,Ccc' 

即在STR開始與任何字A應該在str2中休息。

如何使用Oracle查詢來實現這一目標?

+3

永遠不要將數據存儲爲逗號分隔的項目。這隻會導致你很多問題。 SQL不是爲此設計的,而是具有單獨的行。 – jarlh

+0

@ jarlh評論的補充 - 您可以使用嵌套表格或其他集合類型。 – Rachcha

回答

3

這是str中任何以A開頭的單詞都應該在str1中休息,全部在str2中休息。

爲了實現它在純SQL,我會用以下內容:

  • REGEXP_SUBSTR
  • LISTAGG
  • SUBSTR
  • 內嵌視圖

因此,首先我將使用這裏演示的技術分割逗號分隔的字符串,如Split single comma delimited string into rows所示。

然後,我將按順序使用LISTAGG將它們聚合。

例如,

SQL> WITH 
    2 t1 AS (
    3 SELECT 'Aaa,Bbb,Abb,Ccc' str FROM dual 
    4  ), 
    5 t2 AS (
    6 SELECT trim(regexp_substr(str, '[^,]+', 1, LEVEL)) str 
    7 FROM t1 
    8 CONNECT BY LEVEL <= regexp_count(str, ',')+1 
    9 ORDER BY str 
10  ) 
11 SELECT 
12 (SELECT listagg(str, ',') WITHIN GROUP(
13 ORDER BY NULL) str1 
14 FROM t2 
15 WHERE SUBSTR(str, 1, 1)='A' 
16 ) str1, 
17 (SELECT listagg(str, ',') WITHIN GROUP(
18 ORDER BY NULL) str 
19 FROM t2 
20 WHERE SUBSTR(str, 1, 1)<>'A' 
21 ) str2 
22 FROM dual 
23/

STR1  STR2 
---------- ---------- 
Aaa,Abb Bbb,Ccc 

SQL> 

WITH條款只是爲了演示的目的,您的真實場景中,與第取出並直接使用你的表名。儘管使用WITH子句看起來很整齊。

0

使用regext表達式和ListAg函數。

注意:LISTAGG函數自Oracle 11g起可用!

select listagg(s.name, ',') within group (order by name) 
    from (select regexp_substr('Aaa,Bbb,Abb,Ccc,Add,Ddd','[^,]+', 1, level) name from dual 
     connect by regexp_substr('Aaa,Bbb,Abb,Ccc,Add,Ddd', '[^,]+', 1, level) is not null) s 
group by decode(substr(name,1,1),'A', 1, 0); 
+0

OP想要兩個不同的列。 –

0

該查詢爲您提供了兩種不同的行所需的輸出:

with temp as (select trim (both ',' from 'Aaa,Bbb,Abb,Ccc') as str from dual), 
    base_table as 
     ( select trim (regexp_substr (t.str, 
              '[^' || ',' || ']+', 
              1, 
              level)) 
         str 
       from temp t 
      connect by instr (str, 
          ',', 
          1, 
          level - 1) > 0), 
    ult_table as 
     (select str, 
       case upper (substr (str, 1, 1)) when 'A' then 1 else 2 end 
        as l 
      from base_table) 
select listagg (case when l = 1 then str else null end, ',') 
      within group (order by str) 
      str1, 
     listagg (case when l = 2 then str else null end, ',') 
      within group (order by str) 
      str2 
    from ult_table; 

輸出

  L STR 
---------- -------------------------------------------------------------------------------- 
     1 Aaa,Abb                   
     2 Bbb,Ccc  
+0

OP想要兩個不同的列。 –

+0

@ LalitKumarB-感謝您的注意。編輯代碼。 – Rachcha