【问题标题】:Convert one sql cell data into multiple rows and two columns将一个sql单元格数据转换成多行两列
【发布时间】:2019-12-11 12:54:36
【问题描述】:

我有一个 SQL 表,其中有一个 nvarchar(MAX) 列,其中多个条形码及其日期时间值以这种格式存储:

2238455|12/10/2019 03:07:55 PM;2238452|12/10/2019 03:13:39 PM;2238454|12/10/2019 03:25:04 PM;2238453|12/10/2019 03:26:44 PM**

条码及其日期时间使用分号; 与其他条码分隔,而条码及其日期时间使用管道| 分隔。

我想在条形码和日期时间两列中显示它们。像这样。

Barcode  DateTime
-------------------------------
2238455  12/10/2019 03:07:55 PM
2238452  12/10/2019 03:13:39 PM
2238454  12/10/2019 03:25:04 PM
2238453  12/10/2019 03:26:44 PM

一个单元格中的条形码数量不是固定的,它可以变化。是否可以将此数据转换为所需的格式?我想写一个存储过程或一个视图。

【问题讨论】:

  • 您的 SQL Server 版本是多少?

标签: sql-server datetime split


【解决方案1】:

如果您使用 SQL Server 2016+,您可以使用STRING_SPLIT() 尝试以下方法:

表:

CREATE TABLE Data (
   TextData nvarchar(max)
)
INSERT INTO Data 
   (TextData)
VALUES
   (N'2238455|12/10/2019 03:07:55 PM;2238452|12/10/2019 03:13:39 PM;2238454|12/10/2019 03:25:04 PM;2238453|12/10/2019 03:26:44 PM')

声明:

SELECT 
   LEFT(s.[value], CHARINDEX(N'|', s.[value]) - 1) AS Barcode,
   RIGHT(s.[value], LEN(s.[value]) - CHARINDEX(N'|', s.[value])) AS [DateTime]
FROM Data d
CROSS APPLY STRING_SPLIT(d.TextData, N';') s

结果:

Barcode DateTime
2238455 12/10/2019 03:07:55 PM
2238452 12/10/2019 03:13:39 PM
2238454 12/10/2019 03:25:04 PM
2238453 12/10/2019 03:26:44 PM

【讨论】:

    【解决方案2】:

    对于旧版本,您可以使用此函数将字符串转换为表格

    create Function [dbo].[fn_StringToTable] 
    (
        @List Varchar(max)
    )
    RETURNS @Table TABLE (barcode VARCHAR(100), newdate VARCHAR(100))
    AS
    BEGIN
        IF RIGHT(@List, 1) <> ';'
        SELECT @List = @List + ';'
    
        DECLARE @Pos    BIGINT,
                @OldPos BIGINT,
                @rowval varchar(100)
        SELECT  @Pos    = 1,
                @OldPos = 1
    
        WHILE   @Pos < LEN(@List)
            BEGIN
                SELECT @Pos = CHARINDEX(';', @List, @OldPos)
                select @rowval = LTRIM(RTRIM(SUBSTRING(@List, @OldPos, @Pos - @OldPos)))
    
                INSERT INTO @Table(barcode, newdate)
                SELECT SUBSTRING(@rowval,1,CHARINDEX('|',@rowval)-1),
                       SUBSTRING(@rowval,CHARINDEX('|',@rowval)+1,LEN(@rowval)) 
    
                SELECT  @OldPos = @Pos + 1
            END
    
        RETURN
    END
    

    然后用字符串调用这个函数

    select * from  [dbo].[fn_StringToTable] ('2238455|12/10/2019 03:07:55 PM;2238452|12/10/2019 03:13:39 PM;2238454|12/10/2019 03:25:04 PM;2238453|12/10/2019 03:26:44 PM')
    

    输出

    barcode newdate
    2238455 12/10/2019 03:07:55 PM
    2238452 12/10/2019 03:13:39 PM
    2238454 12/10/2019 03:25:04 PM
    2238453 12/10/2019 03:26:44 PM
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-01
      相关资源
      最近更新 更多