2014-05-14 51 views
1

因此,假設,例如,我有具有以下的表:id, address
我想將address列分成3列:number, street, city當地址的格式爲123, FakeStreet, FakeCity時。由分隔符分割的列分成多個列(其可以是或可以不是在那裏)

但是,這裏是抓住!並非address列中的每個值都有一個數字或城市;其中一些只有街道名稱。在這種情況下,地址只會看起來像FakeStreet,它應該填寫數字和城市的NULL

示例輸入:

id  address 
-------------- 
1  123, fake street, fakCity 
2  31, barrington, anotherCity 
3  main street 
4  25, york street, yetAnotherCity 

輸出:

id  num streetName cityName 
------------------------------------ 
1  123 fake street fakeCity 
2  31  barrington anotherCity 
3  NULL main street NULL 
4  25  york street yetAnotherCity 

另外,我可以假設該地址將或者僅具有街道名稱,或整個地址。

有沒有辦法使用SQL或PL SQL來做到這一點?否則,我想我將不得不將它分成兩個單獨的查詢,在sql之外修改它們,然後將兩個查詢的結果放在一起。我想要再多一點...緊湊,因爲缺乏更好的術語。

啊,我還想提一下,我只需要拆分列作爲SELECT的結果。我不想實際修改表結構。

謝謝。

回答

2

你需要做的事打破字符串conditionaly因爲你有你的規則I can assume that the address will either have only the street name, or the entire address.你需要的查詢,這是一個:

select 
id, 
case when instr(address,',') >= 1 
    then REGEXP_SUBSTR(address, '[^,]+', 1, 1) 
    else null end num, 
case when instr(address,',') >= 1 
    then REGEXP_SUBSTR(address, '[^,]+', 1, 2) 
    else address end street, 
case when instr(address,',') >= 1 
    then REGEXP_SUBSTR(address, '[^,]+', 1, 3) 
    else null end city 
from ads 

此功能REGEXP_SUBSTR(address, '[^,]+', 1, 1)它是基於正則表達式[^,]+這意味着什麼讓您列一個子串是不是一個,第一個1是函數將評估字段address和第二個正則表達式的N次發生的起始位置。

看到這裏在小提琴:http://sqlfiddle.com/#!4/dd1901/8

+0

完美,謝謝! – Rickkwa

2

PL/SQL對於這類操作並不是非常方便,但可以使用REGEXP_SUBSTRING(),類似於;

SELECT "id", 
    CASE WHEN REGEXP_SUBSTR("address", ',', 1, 2) IS NULL 
     THEN NULL 
     ELSE REGEXP_SUBSTR("address", '[^,]*', 1, 1) END num, 
    CASE WHEN REGEXP_SUBSTR("address", ',', 1, 2) IS NULL 
     THEN "address" 
     ELSE TRIM(REGEXP_SUBSTR("address", '[^,]*', 1, 2)) END streetName, 
    CASE WHEN REGEXP_SUBSTR("address", ',', 1, 2) IS NULL 
     THEN NULL 
     ELSE TRIM(REGEXP_SUBSTR("address", '[^,]*', 1, 3)) END cityName 
FROM mytable; 

An SQLfiddle to test with

您可以縮短有些使用公共表表達式的查詢,但我猜想這是一次性操作,而不是要在性能敏感的設置:)

相關問題