Question

So suppose, for example, I have a table that has the following columns: id, address
I want to split the address column into 3 columns: number, street, city when the address is in the format like 123, FakeStreet, FakeCity.

But here's the catch! Not every value in the address column has a number or city; some of them only have the street name. In this case, the address would simply look like FakeStreet and it should fill in NULL for the number and city.

Example Input:

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

Output:

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

Also, I can assume that the address will either have only the street name, or the entire address.

Is there a way I can do this using SQL or PL SQL? Else, I'm thinking I'm going to have to split this into two separate queries, modify them outside of sql, then put the results of the two queries back together. I'd like to have something a little more... compact for a lack of a better term.

Ah, I'd also like to mention that I only need the split columns as the result of a SELECT. I'm not looking to actually modify the table structure.

Thanks.

Was it helpful?

Solution

You need to break the string conditionaly as you have your rule I can assume that the address will either have only the street name, or the entire address. the query you need is this one:

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

This function REGEXP_SUBSTR(address, '[^,]+', 1, 1) it is getting a substring from your column based on a regular expression [^,]+ which mean anything that is not a , the first 1 is the start position that the function will evaluate of the field address and the second 1 the N occurency of the regular expression.

See it here on fiddle: http://sqlfiddle.com/#!4/dd1901/8

OTHER TIPS

PL/SQL isn't extremely convenient for this kind of operations, but you could use REGEXP_SUBSTRING(), something like;

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.

You may be able to shorten the query somewhat using a common table expression, but I'm assuming this is a one time operation, not something you want to do in a performance sensitive setting :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top