2013-01-23 155 views
0

我面对的困难,更是15万所记录的客户表中有包含超过一个值(电话)的电话号码列用空格,逗号,短划线,点等中分离出的原始列值是VARCHAR类型最大30.我需要一种方法来检查这些值,并将它们分割成一个新的表中的列相等,然后通过从除去任何特殊字符正常化他们在他们里面。新的列值都不应超过10位。拆分列多个值

查找低于目前的表,清楚地描绘了当前的混乱的选择查询结果。柱NO_(ΠΕxxxxxx)是Customer Unique Identifier。柱Phone No_是凌乱一个

- List item 

-**No_**  **Phone No_** 
-ΠΕ000586 2310836590 
-ΠΕ000589 2310.443602/6977.226818 
-ΠΕ000591 2310740215 
-ΠΕ000593 2310228976 
-ΠΕ000598 2310444604 
-ΠΕ000606 2310265616/6939686560 
-ΠΕ000611 2310.227932(AΔΕΡΦΗ ΚΟΚΚΑΛΑ) 
-ΠΕ000621 2310826921/6979552442 
-ΠΕ000626 2310846216 
-ΠΕ000629 2310931574 
-ΠΕ000630 6977629688, 2310320441 
-ΠΕ000631 2310.260886/6973.999840 
-ΠΕ000633 2310.288408/342456/6944.503637 
-ΠΕ000636 2310440143/6978008313 
-ΠΕ000637 2310425655/6945365400 
-ΠΕ000646 944111072 
-ΠΕ000652 2310.201923,6942.693372 
-ΠΕ000667 2310.482194/6977394456 
-ΠΕ000675 6949199051 

通过分离每个数字/, - 或空间必须被分离成新的列

任何文本必须被去除。

少于10位数任何数量的序列,如果序列具有6位数必须加入前缀,如果序列具有9数字和第一个数字序列的始于,数6必须添加为前缀。 对于实施例

the number 342456 must become 2310342456 and the number 944111072 must become 694411072 

的10个数字的数字序列之间的任何点(。)必须被移除以有一个唯一的数字 对于实施例

the number 231.282414 must be 231282414 or 6942.693372 must be 6942693372 

任何帮助非常感谢

+2

你尝试过什么?为什么你的问题像需求规格说明文件一样阅读? – Raj

回答

0

例如

if object_id('splitNums') is not null 
    drop function splitNums 
go 

create function splitNums(@nums varchar(30)) 
returns @tr table (n1 varchar(10), n2 varchar(10), n3 varchar(10), n4 varchar(10), n5 varchar(10)) as 
begin 
    declare @v varchar(10) 
    declare @i int 
    insert into @tr values (null, null, null, null, null) 
    declare @ci int = 1 
    while (@ci <= 5) begin 
     if (LEN(@nums) > 0) begin 
      set @i = charindex('/', @nums) 
      if (@i <= 0) 
       set @i = charindex(' ', @nums) 
      if (@i <= 0) 
       set @i = charindex('-', @nums) 
      if (@i <= 0) begin 
       set @v = @nums 
       set @nums = '' 
      end else begin 
       set @v = SUBSTRING(@nums, 1, @i - 1) 
       set @nums = SUBSTRING(@nums, @i + 1, len(@nums) - @i) 
      end 
     end else set @v = '' 
     if (@v = '') break 
     set @v = replace(@v, '.', '') -- more code needed here to remove text 
     if (len(@v) = 6) set @v = '2310' + @v 
     else if (len(@v) = 9 and CHARINDEX('9', @v) = 1) set @v = '6' + @v 
     -- impossible to do dynamic sql in function so... 
     if (@ci = 1) 
      update @tr set n1 = @v 
     else if (@ci = 2) 
      update @tr set n2 = @v 
     else if (@ci = 3) 
      update @tr set n3 = @v 
     else if (@ci = 4) 
      update @tr set n4 = @v 
     else if (@ci = 5) 
      update @tr set n5 = @v 
     set @ci = @ci + 1 
    end 
    return 
end 
go 

declare @t table (
    id nvarchar(10), 
    number nvarchar(30) 
) 

insert into @t (id, number) values 
    (N'ΠΕ000586', '2310836590'), 
    (N'ΠΕ000589', '2310.443602/6977.226818'), 
    (N'ΠΕ000633', '2310.288408/342456/6944.503637') 

select * from @t cross apply dbo.splitNums(number) 
go 
+0

太棒了!你救了我一百万美元 – Borealis

+0

如果阅读不正确,我很抱歉。可能在发布之前我不得不重新修饰它。我是这个领域的新手,我一定会尝试以更可接受的方式表达我的问题。 – Borealis

+0

我没有尝试过任何类似你的代码。只需简单的更新 - 替换查询,每次我必须更改搜索字符,符号等;你的代码给了我更多的批量解决方案。再次thx很多。 – Borealis