Reputation: 2291
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.
Upvotes: 1
Views: 10367
Reputation: 23361
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
Upvotes: 2
Reputation: 180917
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;
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 :)
Upvotes: 2