【问题标题】:Split column multiple values of an SQL 2005 table into new columns of a new temp table将 SQL 2005 表的列多个值拆分为新临时表的新列
【发布时间】:2013-01-23 09:55:16
【问题描述】:

我面临这样一种情况,其中包含超过 150000 条记录的客户表有一个电话号码列,其中包含多个值(电话),由空格、逗号、破折号、点等分隔。原始列值是varchar 类型最大 30。我需要一种方法来检查这些值并将它们拆分为新表的相等列,然后通过从其中删除任何特殊字符来规范化它们。新列的值都不应超过 10 位。

在下面找到当前表的选择查询结果,它清楚地描述了当前的混乱。列号_ (ΠΕ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位,则必须添加2310前缀,如果该数列有9位和第一个序列的数字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

非常感谢任何帮助

【问题讨论】:

  • 你试过什么?为什么您的问题读起来像需求规范文档?

标签: sql sql-server sql-server-2005


【解决方案1】:

例如

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

【讨论】:

  • 太棒了!谢谢你救我一百万
  • 如果读数不正确,我很抱歉。可能我在发布之前不得不重新措辞。我是这个领域的新手,我一定会尝试以更容易接受的方式表达我的问题。
  • 我没有尝试过像你的代码这样的东西。只是简单的更新替换查询,每次我都必须更改搜索字符、符号等;你的代码给了我一个更大的解决方案。再次感谢很多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-16
  • 1970-01-01
  • 2018-11-25
  • 2019-06-05
  • 1970-01-01
相关资源
最近更新 更多