代码之家  ›  专栏  ›  技术社区  ›  earthling

拆分逗号分隔的单元格数据

  •  1
  • earthling  · 技术社区  · 16 年前

    我有一个包含多列的电子表格,其中一列是所有者ID列。问题是,此列包含一个用逗号分隔的所有者ID列表,而不仅仅是一个。

    我已将此电子表格导入到我的SQL数据库(2008),并已完成其他导入任务,现在由于此过程有一个package_id列。

    我需要在我的 parcelOwners 每个parcelid/owner id对的表,但是我不知道如何处理这个问题,因为所有者ID在逗号分隔的列表中。

    我的桌子看起来像这样:

    ImportData
    =================
    owner_id varchar, 
    parcelID int      
    
    sample row (owner_id = '13782, 21431', parcelID = 319)
    
    ParcelOwners
    =================
    ownerID int,
    parcelID int
    
    row from ImportData table should look like:
    ownerID = 13782, parcelID = 319
    ownerID = 21431, parcelID = 319
    

    这对任何人来说都是一种常见的情况吗?如果是这样,你该如何解决这个问题?

    3 回复  |  直到 16 年前
        1
  •  4
  •   Ben Hoffman    16 年前

    下面的函数将逗号分隔列拆分为一个表。然后需要遍历临时表,并将1行插入 parcelOwners 表使用单列中的数据。要使其工作,您需要一个外部循环来迭代 公园业主 表和一个内部循环,循环遍历每一行的@tentable。另外,不要忘记,如果在外循环中出现一行,并且在 owner_id 专栏你什么都不想做。

    CREATE FUNCTION dbo.Split(@String varchar(8000), @Delimiter char(1))       
    returns @temptable TABLE (items varchar(8000))       
    as       
    begin       
        declare @idx int       
        declare @slice varchar(8000)       
    
        select @idx = 1       
            if len(@String)<1 or @String is null  return       
    
        while @idx!= 0       
        begin       
            set @idx = charindex(@Delimiter,@String)       
            if @idx!=0       
                set @slice = left(@String,@idx - 1)       
            else       
                set @slice = @String       
    
            if(len(@slice)>0)  
                insert into @temptable(Items) values(@slice)       
    
            set @String = right(@String,len(@String) - @idx)       
            if len(@String) = 0 break       
        end   
    return       
    end 
    
        2
  •  2
  •   Aaron Silverman    16 年前

    您可以轻松地利用SQL Server的XML函数:

    WITH xmlData (xml_owner_id,parecelID) AS (
        /* make into xml */
        SELECT cast('<x>'+replace(owner_id,',','</x><x>')+'</x>' as XML)  AS xml_owner_id, parecelID
        FROM ImportData
    )
    SELECT x.value('.','int') AS owner_id, parecelID /* split up */
    FROM xmlData
    CROSS APPLY xmlData.xml_owner_id.nodes('//x') AS func(x)
    
        3
  •  1
  •   Community Mohan Dere    9 年前

    (回应@senloe关于如何使用@randomben提供的函数的问题)

    This answer 上一个问题演示了如何使用外部应用将函数应用于表中的每一行。在您的例子中,假设您已经运行了@randomben的代码来创建dbo.split函数,那么语法如下所示:

    INSERT INTO ParcelOwners (ownerId, parcelID)
    SELECT CONVERT(int, Results.items), ImportData.parcelID
    FROM ImportData
    OUTER APPLY dbo.Split(ImportData.owner_id, ',') AS Results
    

    (我现在没有访问SQL Server的权限,所以我还没有尝试过。您可以在不使用第一行的情况下运行它,也就是说,只从select开始,在实际执行插入操作之前查看它将生成什么输出)。