How to split a comma-separated value to columns

后端 未结 30 4099
刺人心
刺人心 2020-11-21 04:38

I have a table like this

Value   String
-------------------
1       Cleo, Smith

I want to separate the comma delimited string into two colu

30条回答
  •  我寻月下人不归
    2020-11-21 05:08

    I encountered a similar problem but a complex one and since this is the first thread i found regarding that issue i decided to post my finding. i know it is complex solution to a simple problem but i hope that i could help other people who go to this thread looking for a more complex solution. i had to split a string containing 5 numbers (column name: levelsFeed) and to show each number in a separate column. for example: 8,1,2,2,2 should be shown as :

    1  2  3  4  5
    -------------
    8  1  2  2  2
    

    Solution 1: using XML functions: this solution for the slowest solution by far

    SELECT Distinct FeedbackID, 
    , S.a.value('(/H/r)[1]', 'INT') AS level1
    , S.a.value('(/H/r)[2]', 'INT') AS level2
    , S.a.value('(/H/r)[3]', 'INT') AS level3
    , S.a.value('(/H/r)[4]', 'INT') AS level4
    , S.a.value('(/H/r)[5]', 'INT') AS level5
    FROM (            
        SELECT *,CAST (N'' + REPLACE(levelsFeed, ',', '')  + ' ' AS XML) AS [vals]
        FROM Feedbacks 
    )  as d
    CROSS APPLY d.[vals].nodes('/H/r') S(a)
    

    Solution 2: using Split function and pivot. (the split function split a string to rows with the column name Data)

    SELECT FeedbackID, [1],[2],[3],[4],[5]
    FROM (
        SELECT *, ROW_NUMBER() OVER (PARTITION BY feedbackID ORDER BY (SELECT  null)) as rn 
    FROM (
        SELECT FeedbackID, levelsFeed
        FROM Feedbacks 
    ) as a
    CROSS APPLY dbo.Split(levelsFeed, ',')
    ) as SourceTable
    PIVOT
    (
        MAX(data)
        FOR rn IN ([1],[2],[3],[4],[5])
    )as pivotTable
    

    Solution 3: using string manipulations functions - fastest by small margin over solution 2

    SELECT FeedbackID,
    SUBSTRING(levelsFeed,0,CHARINDEX(',',levelsFeed)) AS level1,
    PARSENAME(REPLACE(SUBSTRING(levelsFeed,CHARINDEX(',',levelsFeed)+1,LEN(levelsFeed)),',','.'),4) AS level2,
    PARSENAME(REPLACE(SUBSTRING(levelsFeed,CHARINDEX(',',levelsFeed)+1,LEN(levelsFeed)),',','.'),3) AS level3,
    PARSENAME(REPLACE(SUBSTRING(levelsFeed,CHARINDEX(',',levelsFeed)+1,LEN(levelsFeed)),',','.'),2) AS level4,
    PARSENAME(REPLACE(SUBSTRING(levelsFeed,CHARINDEX(',',levelsFeed)+1,LEN(levelsFeed)),',','.'),1) AS level5
    FROM Feedbacks
    

    since the levelsFeed contains 5 string values i needed to use the substring function for the first string.

    i hope that my solution will help other that got to this thread looking for a more complex split to columns methods

提交回复
热议问题