2012-04-14 53 views
1

我需要將一個表中的字符串拆分爲另一個表中的兩列。有幾種不同的數字和規則,但沒有明確的分隔符。我可以使用SUBSTR和INSTR組合嗎?還是我需要在PL/SQL中使用if-then循環來滿足所有規則?將字符串拆分爲兩列(SQL或PL/SQL)

輸入表

5 Kent Street 
3 A lindt Street 
2/15 bold Street 
9/34-36 carmen Road 
12/5a sandford Street 

結果

Number |Street 
-------------------- 
5  |Kent Street 
3A  |lindt Street 
2/15 |bold Street 
9/34-36 |carmen Road 
12/5a |sandford Street 
+0

什麼數據庫?例如SQL Server,Oracle,MySQL等 – 2012-04-14 13:27:01

+0

@JeffreyKemp:我猜Oracle(因爲標題中的「PL/SQL」) – 2012-04-14 13:31:30

+1

你說有多種規則和類型的數字,但是你不告訴我們你需要支持什麼樣的規則和格式。您的示例數據都可以簡單地通過使用第一個空格字符作爲分隔符來解析。 – 2012-04-14 17:55:54

回答

2

我不會在pl/sql中這樣做,這實在沒有必要。

Oracle SQL具有REGEXP_SUBSTR,REGEXP_REPLACE,REGEXP_COUNT。您還可以在SELECT子句中放入IF和CASE表達式。轉到SQL參考「函數」部分:http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions.htm#i1482196

您的數據集包含一些有趣的變體 - 房屋/建築物編號中的字母和分數。你還沒有的東西是街道名稱(例如波士頓的Melnea Cass Boulevard)或街道名稱(連接/缺失(「Broadway」)或不尋常的(「Cedar Passway」)'街道'指示符)。

從sample_data開始,作爲重構查詢來保存輸入數據。你可能會有一個表或視圖或其他東西。

現在我們假設每個街道名稱都有兩個單詞。我們首先用REGEXP_COUNT對它們進行計數。這是子查詢COUNTED_DATA,其值爲WORDS作爲單詞的計數。請注意,如果在輸入數據行的末尾沒有一個空格,則會爲每行輸入添加一個空格,以便計數正確。

我搜索每個字作爲

[^ ]+[ ]+ 

也就是說,一個或多個非空格後面跟着一個或多個空格。我不想使用零個或多個空格([] *),因爲這是不明確的。

然後我們使用一個正則表達式來挑選出最後兩個單詞和第一個單詞(單詞減2)的單詞。

這裏的結果:

with sample_data as (
    select '5 Kent Street' as addr from dual 
    union all select '3 A lindt Street' as addr from dual 
    union all select '2/15 bold Street' as addr from dual 
    union all select '9/34-36 carmen Road' as addr from dual 
    union all select '12/5a sandford Street' from dual 
) 
select 
    counted_data.addr as "Original Address", 
    substr (regexp_replace (addr || ' ', '(([^ ]+[ ]+){' || (words-2) ||'})([^ ].*)','\1'), 1, 10) as "Number", 
    substr (trim (regexp_replace (addr || ' ', '(([^ ]+[ ]+){' || (words-2) ||'})([^ ].*)','\3')), 1, 25) as "Street" 
from 
(
    select sample_data.addr, regexp_count(addr || ' ', '[ ]+') as words 
    from sample_data 
) counted_data 

Original Address  Number  Street     
--------------------- ---------- ------------------------- 
5 Kent Street   5   Kent Street    
3 A lindt Street  3 A  lindt Street    
2/15 bold Street  2/15  bold Street    
9/34-36 carmen Road 9/34-36 carmen Road    
12/5a sandford Street 12/5a  sandford Street   

爲了使這一可讀我用「SUBSTR」,以減少輸出列的長度。 (「COLUMN」在SQL Developer中不起作用。)

+0

嗨安德魯感謝您的 – user1332821 2012-04-16 01:12:24

+0

答覆。這項任務的要求是使用PL/SQL來解決這個問題。 – user1332821 2012-04-16 01:13:50

+0

輸入是CLOB,VARCHAR2,TABLE VARCHAR2嗎? – 2012-04-16 14:16:54

0

我可以建議你三種可能性:

  1. 如果分隔符是簡單明瞭的,你建議組合使用SUBSTR和INSTR。

  2. 如果您的數據庫支持正則表達式函數,並且它簡單地將您的地址字段與正則表達式匹配使用它。例如MySQL有REGEXP

  3. 但是,如果字符串的解析是複雜的,變體太多,那麼使用完整的編程語言的外部腳本。

    連接到數據庫,例如在Java中,處理字符串並將結果插入到新表中。如果您的行數很大,請記住使用批量操作,因此速度會更快。