【问题标题】:Splitting comma delimited cell data拆分逗号分隔的单元格数据
【发布时间】:2011-03-18 02:23:00
【问题描述】:

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

我已将此电子表格导入我的 sql 数据库 (2008) 并完成了其他导入任务,现在有了一个 parcel_id 列作为此过程的结果。

我需要在我的parcelOwners 表中为每个 parcelID/ownerID 对创建一个条目,但我不知道如何在所有者 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

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

【问题讨论】:

标签: tsql sql-server-2008 import split


【解决方案1】:

以下函数会将您的逗号分隔列拆分为一个表格。然后,您需要遍历临时表并使用单列中的数据将 1 行插入到您的 parcelOwners 表中。要使其工作,您将需要一个外部循环来迭代 parcelOwners 表和一个内部循环来迭代每一行的 @temptable。另外,不要忘记,如果您在外部循环中遇到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 

【讨论】:

  • 我不熟悉 sql 中的循环。我一直在玩这个,不太确定 sql 期待什么。我知道我需要做类似的事情: foreach row in ImportData foreach row2 in split(ownerID, ',') insert into Parcelowners(parcelId, ownerID) 也许我会制作一个快速控制台应用程序来为我执行此操作,因为它是一次拍摄。
【解决方案2】:

您可以利用 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】:

    (针对@senloe关于如何使用@RandomBen提供的函数的问题)

    This answer 对上一个问题显示了如何使用 OUTER APPLY 将函数应用于表中的每一行。在您的情况下,假设您已经运行 @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 开始,看看它之前会生成什么输出你实际上是在做 INSERT)。

    【讨论】:

    • 谢谢,我会调查的。学习新事物总是很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-13
    • 2015-03-07
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    相关资源
    最近更新 更多