例如,假设我有一个包含以下列的表: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
只需要拆分列。我不打算实际修改表格结构。
感谢。
答案 0 :(得分: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;
您可以使用公用表表达式稍微缩短查询,但我假设这是一次性操作,而不是您想要在性能敏感设置中执行的操作:)
答案 1 :(得分:2)
你需要打破字符串条件,因为你有你的规则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
的位置,以及第二个1
正则表达式的N出现的位置。
在这里查看小提琴:http://sqlfiddle.com/#!4/dd1901/8