将SQL中的行分隔为由短划线( - )和管道(|)分隔的不同列

问题描述 投票:0回答:1

所以我试图将一些数据从管道分隔的行拆分成不同的列,这是行:Row

我有一个适用于它的功能,如下所示:

CREATE FUNCTION dbo.TestPipeSplit
(
  @multiwordstring VARCHAR(255),
  @wordnumber      NUMERIC
)
returns VARCHAR(255)
AS

  BEGIN
  DECLARE @remainingstring VARCHAR(255)
  SET @remainingstring=@multiwordstring

  DECLARE @numberofwords NUMERIC
  SET @numberofwords=(LEN(@remainingstring) - LEN(REPLACE(@remainingstring, '|', '')) + 1)

  DECLARE @word VARCHAR(50)
  DECLARE @parsedwords TABLE
  (
     line NUMERIC IDENTITY(1, 1),
     word VARCHAR(255)
  )

  WHILE @numberofwords > 1
    BEGIN
        SET @word=LEFT(@remainingstring, CHARINDEX('|', @remainingstring) - 1)

        INSERT INTO @parsedwords(word)
        SELECT @word

        SET @remainingstring= REPLACE(@remainingstring, Concat(@word, '|'), '')
        SET @numberofwords=(LEN(@remainingstring) - LEN(REPLACE(@remainingstring, '|', '')) + 1)

        IF @numberofwords = 1
          BREAK

        ELSE
          CONTINUE
    END

正如您在屏幕截图中看到的那样,有一个黄色突出显示,我需要能够用破折号分隔这些行。所以我使用的工具将数据导入SQL,每个破折号分隔的项目都是一个用户信息,我需要能够将每个用户(破折号)分开,然后将管道分隔的信息分成不同的列。我能够完成第二部分,但我坚持使用破折号。我尝试将相同的管道功能应用于破折号,但我已经让脚本运行了一个多小时而且没有任何结果。

谢谢 !!!

sql-server
1个回答
1
投票

这是使用一点XML的一种方法

这也假设您已知或最大数量的职位。否则你需要DYNAMIC

此外,发布图像没有帮助。

Declare @YourTable table (ID int,SomeCol varchar(max))
Insert Into @YourTable values
 (1,'123|abc|456')
,(2,'789|def|012')

Select A.ID
     ,B.*
 From @YourTable A
 Cross Apply (
                Select Pos1 = ltrim(rtrim(xDim.value('/x[1]','varchar(max)')))
                      ,Pos2 = ltrim(rtrim(xDim.value('/x[2]','varchar(max)')))
                      ,Pos3 = ltrim(rtrim(xDim.value('/x[3]','varchar(max)')))
                      ,Pos4 = ltrim(rtrim(xDim.value('/x[4]','varchar(max)')))
                      ,Pos5 = ltrim(rtrim(xDim.value('/x[5]','varchar(max)')))
                      ,Pos6 = ltrim(rtrim(xDim.value('/x[6]','varchar(max)')))
                      ,Pos7 = ltrim(rtrim(xDim.value('/x[7]','varchar(max)')))
                      ,Pos8 = ltrim(rtrim(xDim.value('/x[8]','varchar(max)')))
                      ,Pos9 = ltrim(rtrim(xDim.value('/x[9]','varchar(max)')))
                From  (Select Cast('<x>' + replace((Select replace(SomeCol,'|','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml) as xDim) as A 
             ) B

返回

ID  Pos1    Pos2    Pos3    Pos4    Pos5    Pos6    Pos7    Pos8    Pos9
1   123     abc     456     NULL    NULL    NULL    NULL    NULL    NULL
2   789     def     012     NULL    NULL    NULL    NULL    NULL    NULL

如果你喜欢它作为TVF,请看看How to extract values from column and update result in another column

© www.soinside.com 2019 - 2024. All rights reserved.