从sql列中拆分数据并将其保存在sql存储过程中的另一个表中的最有效方法是啥[重复]

Posted

技术标签:

【中文标题】从sql列中拆分数据并将其保存在sql存储过程中的另一个表中的最有效方法是啥[重复]【英文标题】:What is the most efficient way of Splitting the data from sql column and saving it in another table in sql stored procedure [duplicate]从sql列中拆分数据并将其保存在sql存储过程中的另一个表中的最有效方法是什么[重复] 【发布时间】:2021-07-14 07:59:33 【问题描述】:

我有一个结构如下的表

Id Data
1 5#SkipData#Data1,Data2,Data3
2 5#SkipData#Data4
3 5#SkipData#Data5,Data6,Data7,Data8,Data9

我想将数据放在另一个表格中,格式如下:

Id SeperatedData
1 Data1
1 Data2
1 Data3
2 Data4
3 Data5
3 Data6
3 Data7
3 Data8
3 Data9

skipdata 的长度为 5,而所有数据的长度固定为 13。如表中所述,数据由逗号 (,) 符号分隔。 目前,这是在存储过程中使用交叉应用实现的,性能很差。

下面的数据转换是在sql存储过程中完成的。

【问题讨论】:

你试过SPLIT_STRING()吗? 你的 sql server 版本是多少? 没有 SQL Server 2015,运行select @@version 太遗憾了,string_split 到了 SQL 2016,为了您的目的,它的速度要快几个数量级,我会认真考虑升级您的 SQL Server 版本。 这能回答你的问题吗? Split function equivalent in T-SQL? 【参考方案1】:

我使用这个表函数来拆分数据。

CREATE FUNCTION [dbo].[fn_Split_String]
(   
    @Text NVARCHAR(MAX)
    ,@Delimiter CHAR(1)
)
RETURNS @Result TABLE (
    Row INT IDENTITY(1, 1)
    ,String NVARCHAR(MAX)
)
AS
BEGIN

    DECLARE @Lenght INT = LEN(@Text) + 1
            ,@Char CHAR(1) = ''
            ,@Word NVARCHAR(MAX) = ''
            ,@Index INT = 1

    WHILE @Index < @Lenght
        BEGIN
            
            SET @Char = SUBSTRING(@Text, @Index, 1)

            IF (@Char = @Delimiter AND @Word != '')
                BEGIN
                    INSERT INTO @Result VALUES (LTRIM(RTRIM(@Word)))
                    SET @Word = ''
                END
            ELSE
                BEGIN
                    SET @Word += @Char
                END

            SET @Index += 1
        END

    IF (@Word != '')
        BEGIN
            INSERT INTO @Result VALUES (LTRIM(RTRIM(@Word)))
        END

RETURN
END
GO

所以,如果你使用这个函数,你的查询看起来像这样

SELECT
    D.Id
    ,S.String
FROM Data D
CROSS APPLY dbo.fn_Split_String(REPLACE(D.Data, '5#SkipData#', ''), ',') S

【讨论】:

【参考方案2】:

如果所有数据值的长度相同,则可以使用蛮力方法。您需要生成一个数字列表——直到数据值的最大数量。说是5:

select d.id, substring(d.data, 12 + n * 6, 5)
from data d cross join
     (values (0), (1), (2), (3), (4)) v(n)
where substring(d.data, 13 + n * 6, 5) <> '';

您可以使用任何您喜欢的方法来生成数字。你甚至可能有一个方便的数字表。

Here 是一个 dbfiddle。

【讨论】:

以上是关于从sql列中拆分数据并将其保存在sql存储过程中的另一个表中的最有效方法是啥[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何从 SQL Server 表中读取图像数据(存储 word 文档)并将其保存到本地文件夹

如何从存储过程中获取 SQL 字符串结果并将其保存在 C# Windows 应用程序字符串变量中

使用pl / sql或sql在学生表的多个列中拆分数据

sqlSave 在 R 中创建数据框并将其保存到 sql 表

T-SQL基于分隔符拆分列并将拆分后的字符串数组输入到多个表列中

在SQL过程中将一列中的逗号分隔值拆分为多列