Dividere la stringa in righe Oracle SQL

Dopo aver cercato nei forum ho trovato il seguente, ma non funziona: /

Ho un tavolo con il seguente;

ID | Strings 123| abc fgh dwd 243| dfs dfd dfg 353| dfs 424| dfd dfw 523| . . . 

Per favore non che ci siano circa 20.000 righe la mia altra opzione è scrivere una stored procedure per fare questo … Fondamentalmente ho bisogno di dividere le stringhe in modo che ci sia una riga per ognuna come questa

 ID | Strings 123| abc 123| fgh 123| dwd 243| dfs 

e così via…

questo è quello che ho.

 create table Temp AS SELECT ID, strings From mytable; SELECT DISTINCT ID, trim(regexp_substr(str, '[^ ]+', 1, level)) str FROM (SELECT ID, strings str FROM temp) t CONNECT BY instr(str, ' ', 1, level -1) >0 ORDER BY ID; 

Qualsiasi aiuto è apprezzato

Questo dovrebbe fare il trucco:

 SELECT DISTINCT ID, regexp_substr("Strings", '[^ ]+', 1, LEVEL) FROM T CONNECT BY regexp_substr("Strings", '[^ ]+', 1, LEVEL) IS NOT NULL ORDER BY ID; 

Nota come ho usato regexp_substr nella clausola connect by. Questo è il caso di più spazi.


Se si ha un limite superiore prevedibile sul numero di elementi per riga, potrebbe valere la pena confrontare le prestazioni della query ricorsiva sopra con un semplice CROSS JOIN :

 WITH N as (SELECT LEVEL POS FROM DUAL CONNECT BY LEVEL < 10) -- ^^ -- up to 10 substrings SELECT ID, regexp_substr("Strings", '[^ ]+', 1, POS) FROM T CROSS JOIN N WHERE regexp_substr("Strings", '[^ ]+', 1, POS) IS NOT NULL ORDER BY ID; 

Vedi http://sqlfiddle.com/#!4/444e3/1 per una demo dal vivo

Una soluzione più flessibile e migliore che:

  • non dipende dalla prevedibilità del numero di articoli per riga.
  • non dipende dalla colonna ID, la soluzione fornisce risultati corretti indipendentemente dal numero di colonne.
  • non dipende nemmeno dalla parola chiave DISTINCT .

Esistono altri esempi che utilizzano la clausola XMLTABLE e MODEL , si prega di leggere le stringhe delimitate da una virgola in una tabella .

Per esempio,

Senza colonna ID:

 SQL> WITH T AS 2 (SELECT 'abc fgh dwd' AS text FROM dual 3 UNION 4 SELECT 'dfs dfd dfg' AS text FROM dual 5 UNION 6 SELECT 'dfs' AS text FROM Dual 7 UNION 8 SELECT 'dfd dfw' AS text FROM dual 9 ) 10 SELECT trim(regexp_substr(t.text, '[^ ]+', 1, lines.column_value)) text 11 FROM t, 12 TABLE (CAST (MULTISET 13 (SELECT LEVEL FROM dual CONNECT BY instr(t.text, ' ', 1, LEVEL - 1) > 0 14 ) AS sys.odciNumberList )) lines 15 / TEXT ----------- abc fgh dwd dfd dfw dfs dfs dfd dfg 9 rows selected. 

Con la colonna ID:

 SQL> WITH T AS 2 (SELECT 123 AS id, 'abc fgh dwd' AS text FROM dual 3 UNION 4 SELECT 243 AS id, 'dfs dfd dfg' AS text FROM dual 5 UNION 6 SELECT 353 AS Id, 'dfs' AS text FROM Dual 7 UNION 8 SELECT 424 AS id, 'dfd dfw' AS text FROM dual 9 ) 10 SELECT id, trim(regexp_substr(t.text, '[^ ]+', 1, lines.column_value)) text 11 FROM t, 12 TABLE (CAST (MULTISET 13 (SELECT LEVEL FROM dual CONNECT BY instr(t.text, ' ', 1, LEVEL - 1) > 0 14 ) AS sys.odciNumberList )) lines 15 ORDER BY id 16 / ID TEXT ---------- ----------- 123 abc 123 fgh 123 dwd 243 dfs 243 dfd 243 dfg 353 dfs 424 dfd 424 dfw 9 rows selected. SQL> 
 With T As (select 123 as id, 'abc fgh dwd' as strings from dual union select 243 as id, 'dfs dfd dfg' as strings from dual union Select 353 As Id, 'dfs' As Strings From Dual union select 424 as id, 'dfd dfw' as strings from dual ) select distinct id, REGEXP_SUBSTR (Replace(Strings, ' ', ','), '[^,]+', 1, level) as Strings from t Connect By Level <= Length(Regexp_Replace(Replace(Strings, ' ', ','),'[^,]*'))+1 order by id, strings; **********OUTPUT************* ID STRINGS ---------- ----------- 123 abc 123 dwd 123 fgh 243 dfd 243 dfg 243 dfs 353 dfs 424 dfd 424 dfw 9 rows selected