2014-10-16 125 views
4

在搜索論壇後,我想出了以下內容,但它不起作用:/將字符串拆分成行Oracle SQL

我有一個表格,

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

請不有大約20,000行我的另一種選擇是寫一個存儲過程做到這一點...基本上,我需要拆分串起來所以爲每一個這樣的

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

等等...

這就是我。

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; 

任何幫助表示讚賞

+0

我能想到這樣做將是非常低效的唯一途徑。在接收到數據庫的初始響應後,您是否有理由在編程語言中無法做到這一點? – Sam 2014-10-16 15:57:13

回答

5

這應該做的伎倆:

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

通知我如何在連接使用regexp_substr by子句了。這是爲了處理多空間的情況。


如果您對每行項目的數量可預測的上限,則可能值得用一個簡單的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; 

了現場見http://sqlfiddle.com/#!4/444e3/1演示

+0

這是我以爲這樣做的,但它似乎並不接受屬性字符串在「」它告訴我它的無效標識符 – 2014-10-17 00:45:50

+0

@Grant _「屬性字符串[... ]它告訴我它是一個無效的標識符「_ FWIW,當引用時,標識符區分大小寫。也許這是你的問題?或者是一個簡單的錯字?如果不是,那很奇怪?!?如果你無法自己修復它,也許值得另闢蹊徑,只關注這個問題,並提及你的表的確切結構,試圖查詢以及由你的Oracle版本生成的非常準確的錯誤代碼和消息。 – 2014-10-17 08:05:37

+1

所有好的我得到了這個工作謝謝這是我的錯字 – 2014-10-19 04:21:47

-1
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 
+0

實際上有大約20000行,所以我需要一種方法來分割所有的字符串 – 2014-10-17 01:50:49

+0

「WITH T as(...)只是爲了創建你展示的測試數據。所以主要的查詢將是「Select Distinct .... From myTable ...」這樣的事情。然而,其他答案是坦率地更好 – Steve 2014-10-17 12:55:35

3

更靈活,更好的解決方案:

  • 不依賴於每行項目數量的可預測性。
  • 不依賴於ID列,解決方案給出正確的結果,而不考慮列的數量。
  • 甚至不取決於DISTINCT關鍵字。

有使用XMLTABLEMODEL子句其他例子,請閱讀Split comma delimited strings in a table

例如,

沒有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. 

隨着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>