1

我需要将一个表中的字符串拆分为另一个表中的两列。有几种不同的数字和规则,但没有明确的分隔符。我可以使用 SUBSTR 和 INSTR 的组合,还是需要在 PL/SQL 中使用 if-then 循环来满足所有规则?

输入表

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
4

2 回答 2

2

我不会在 pl/sql 中这样做,这真的没有必要。

Oracle SQL 有 REGEXP_SUBSTR、REGEXP_REPLACE、REGEXP_COUNT。您还可以将 IF 和 CASE 表达式放在 SELECT 子句中。转到 SQL 参考,FUNCTIONS 部分:http ://docs.oracle.com/cd/E11882_01/server.112/e26088/functions.htm#i1482196

您的数据集有一些有趣的变化 - 房屋/建筑物编号中的字母和分数。您(还没有)是多个部分的街道名称(例如波士顿的 Melnea Cass Boulevard)或带有串联/缺失(“百老汇”)或不寻常(“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 中不起作用。)

于 2012-04-14T16:22:27.240 回答
0

我可以建议你三种可能性:

  1. 如果分隔字符清晰简单,请按照您的建议使用 SUBSTR 和 INSTR 的组合。

  2. 如果您的数据库支持正则表达式功能,并且将您的地址字段与正则表达式匹配很简单,请使用它。例如 MySQL 有REGEXP

  3. 但是,如果字符串的解析很复杂并且变体太多,那么请使用具有完整编程语言的外部脚本。

    连接到数据库,例如在 Java 中,处理字符串并将结果插入到新表中。如果您的行数很大,请记住使用批量操作,这样会更快。

于 2012-04-14T04:11:43.893 回答