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

时间:2018-09-12 17:15:25

标签: sql-server

因此,我尝试将一些数据从管道定界行拆分为不同的列,这是该行: 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中,每个破折号分隔的项目都是一条用户信息,我需要能够分隔每个用户(破折号),然后将管道分隔的信息段分隔为不同的列。我能够完成第二部分,但是我对破折号感到困惑。 我尝试对破折号应用相同的管道功能,但我将脚本运行了一个多小时,但没有任何反应。

谢谢!!!

1 个答案:

答案 0 :(得分:1)

这是一种使用少量XML的方法

这还假设您知道或最大职位数。否则,您将需要动态

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

示例

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