如何使用子字符串分隔动态数据(不同长度)?

时间:2013-11-19 22:01:24

标签: sql sql-server

我需要一些帮助,根据带有起点和终点的动态范围来分离数据。

例如,一个如下所示的字符串:

N=Chris,,Lane,,M,,
N=Alen,,Smith,,E,,

N =是静态的并且始终相同。我可以在等于之后开始一个子串。另一方面,名称是动态的,并且总是在变化,但是有一个带逗号的终结符。如何使用SQL选择此列的每个段,其中Chris,Lane和M可以显示在First,Last和Middle名称的单独列中?

3 个答案:

答案 0 :(得分:1)

调整this示例

SELECT p.id, REPLACE(p.[1], 'N=', '') Col1, p.[2] Col2, p.[3] Col3, p.[4] Col4, p.[5] Col5, p.[6] Col6, p.[7] Col7
FROM (
  SELECT id, substring(d, start + 2, endPos - Start - 2) token, row_number() OVER (
      PARTITION BY id ORDER BY start
      ) n
  FROM (
    SELECT id, d, n start, charindex(',', d, n + 2) endPos
    FROM num
    CROSS JOIN (
      SELECT id, ',' + d + ',' d
      FROM @m
      ) m
    WHERE n < len(d) - 1
      AND substring(d, n + 1, 1) = ','
    ) d
  ) pvt
Pivot(max(token) FOR n IN ([1], [2], [3], [4], [5], [6], [7])) p

demo

答案 1 :(得分:0)

听起来像......分手功能!!! fn_split()

http://technet.microsoft.com/en-us/library/aa496058(v=sql.80).aspx

CREATE  FUNCTION dbo.fn_Split(@text varchar(8000), @delimiter varchar(20) = ' ')
RETURNS @Strings TABLE
(    
  position int IDENTITY PRIMARY KEY,
  value varchar(8000)   
)
AS
BEGIN

DECLARE @index int
SET @index = -1 

WHILE (LEN(@text) > 0) 

  BEGIN 
    SET @index = CHARINDEX(@delimiter , @text)  
    IF (@index = 0) AND (LEN(@text) > 0)  
      BEGIN  
        INSERT INTO @Strings VALUES (@text)
          BREAK  
      END 

    IF (@index >= 1)  
      BEGIN  
        INSERT INTO @Strings VALUES (LEFT(@text, @index - 1))   
        SET @text = RIGHT(@text, (LEN(@text) - @index))  
      END 
    ELSE
      SET @text = RIGHT(@text, (LEN(@text) - @index)) 
    END
  RETURN

END
GO

SELECT * FROM dbo.fn_Split('N=Chris,,,,,Lane,,M,,',',')

或者你可以根据自己的喜好调整....

SELECT [1] AS FirstName,[2],[3] AS LastName,[4],[5] AS MiddleInitial,[6]
FROM (
    SELECT POSITION, VALUE 
    FROM dbo.fn_Split('N=Chris,,Lane,,M,,',',')
) p
PIVOT (MAX(VALUE) FOR POSITION IN ([1],[2],[3],[4],[5],[6])) AS pvt

不想做所有的工作,但是downvote让我心烦意乱......我不知道为什么当我被投票时感觉如此个人......我需要努力。 =(

答案 2 :(得分:0)

它不漂亮,但您可以使用charindexlocate进行解析:

select
  substring(text, 3, charindex(',', text) - 3) firstName,
  substring(text, charindex(',', text, charindex(',', text) + 1) + 1, charindex(',', text, charindex(',', text, charindex(',', text) + 1) + 1) - charindex(',', text, charindex(',', text) + 1) - 1) lastName, 
  substring(text, charindex(',', text, charindex(',', text, charindex(',', text, charindex(',', text) + 1) + 1) + 1) + 1, charindex(',', text, charindex(',', text, charindex(',', text, charindex(',', text, charindex(',', text) + 1) + 1) + 1) + 1) - charindex(',', text, charindex(',', text, charindex(',', text, charindex(',', text) + 1) + 1) + 1) - 1) middleName,
from
  t

SQLFiddle here