Can any one please guide,how to split this result,

  • Hi Friends,

    Declare @t Table

    (

    id int,

    EmpName nvarchar(500),

    status char(5),

    Repair int

    )

    Insert Into @t

    Select 1,'Arun,Balu','Yes',25 Union All

    Select 2,'Nagu','No',20 Union All

    Select 3,'Mani','No',45 Union All

    Select 4,'XXX,YYY','No',5

    select * from @t

    My Required Output is Like This

    id EmpName status repair

    1ArunYes 25

    1BaluYes 25

    2NaguNo 20

    3ManiNo 45

    4XXX No 5

    4YYYNo 5

  • SELECT s.*, x.*

    FROM @t s

    CROSS APPLY (

    SELECT EmpNamePart = SUBSTRING(s.EmpName, b, e), b, e

    FROM (

    SELECT

    n.n AS b, -- delimiter at beginning of string

    ISNULL(NULLIF(CHARINDEX(',', s.EmpName, n.n+1), 0), LEN(s.EmpName)+1)-1 AS e -- delimiter at end of string

    FROM (SELECT TOP 200 [n] = ROW_NUMBER() OVER(ORDER BY [name]) FROM master.dbo.syscolumns) n -- generates 200 rows where n = 1 to 200

    WHERE SUBSTRING(',' + s.EmpName + ',', n.n, 1) = ','

    AND n < LEN(s.EmpName)

    ) d

    ) x

    ORDER BY s.ID

    “Write the query the simplest way. If through testing it becomes clear that the performance is inadequate, consider alternative query forms.” - Gail Shaw

    For fast, accurate and documented assistance in answering your questions, please read this article.
    Understanding and using APPLY, (I) and (II) Paul White
    Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden

  • There are several ways to split strings in addition to the method Chris mentioned. Google "SQL Server Split Strings," choose one that seems to work, and apply that methodology to your code.

    Just an FYI: if you don't understand what Chris did, research it and ask questions. Don't just use the code without understanding it. It'll get you into trouble when something breaks and you can't tell your boss why you did what you did.

    Brandie Tarvin, MCITP Database AdministratorLiveJournal Blog: http://brandietarvin.livejournal.com/[/url]On LinkedIn!, Google+, and Twitter.Freelance Writer: ShadowrunLatchkeys: Nevermore, Latchkeys: The Bootleg War, and Latchkeys: Roscoes in the Night are now available on Nook and Kindle.

  • Really i didn't understand the solution that is posted here.Please can some one explain me what exactly the Query is doing.

  • sharath.chalamgari (10/21/2010)


    Really i didn't understand the solution that is posted here.Please can some one explain me what exactly the Query is doing.

    Sure. Here's a start:

    -- create a sequence table (this would ideally be properly formed with a clustered index)

    DROP TABLE #Numbers

    CREATE TABLE #Numbers (n INT)

    INSERT INTO #Numbers (n)

    SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL

    SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL

    SELECT 11 UNION ALL SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15 UNION ALL

    SELECT 16

    -- what does it look like?

    SELECT *

    FROM #Numbers

    -- Create and populate a string variable.

    -- Commas are in positions 2 and 8 within the string

    DECLARE @MyString VARCHAR(16)

    SET @MyString = 'a,short,string'

    -- Query the sequence (numbers) table, restricting the output

    -- to numbers which are the positions of commas in the string

    SELECT *

    FROM #Numbers Nos

    WHERE SUBSTRING(@MyString, Nos.n, 1) = ','

    -- retrieve everything before each comma:

    SELECT LEFT(@MyString, Nos.n - 1)

    FROM #Numbers Nos

    WHERE SUBSTRING(@MyString, Nos.n, 1) = ','

    “Write the query the simplest way. If through testing it becomes clear that the performance is inadequate, consider alternative query forms.” - Gail Shaw

    For fast, accurate and documented assistance in answering your questions, please read this article.
    Understanding and using APPLY, (I) and (II) Paul White
    Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden

  • Thanks Chris now i got the idea of how you achived this.

  • Chris Morris-439714 (10/21/2010)


    SELECT s.*, x.*

    FROM @t s

    CROSS APPLY (

    SELECT EmpNamePart = SUBSTRING(s.EmpName, b, e), b, e

    FROM (

    SELECT

    n.n AS b, -- delimiter at beginning of string

    ISNULL(NULLIF(CHARINDEX(',', s.EmpName, n.n+1), 0), LEN(s.EmpName)+1)-1 AS e -- delimiter at end of string

    FROM (SELECT TOP 200 [n] = ROW_NUMBER() OVER(ORDER BY [name]) FROM master.dbo.syscolumns) n -- generates 200 rows where n = 1 to 200

    WHERE SUBSTRING(',' + s.EmpName + ',', n.n, 1) = ','

    AND n < LEN(s.EmpName)

    ) d

    ) x

    ORDER BY s.ID

    Hi Chirs,

    Really super your coding and techinque. But i have small issue in this code

    For Eg

    Declare @t Table

    (

    id int,

    EmpName nvarchar(500),

    status char(5),

    Repair int

    )

    Insert Into @t

    Select 2,'Nagu','No',20 Union All

    Select 4,'XXX,YYY','No',5 Union all

    Select 5,'Anil, Rakesh, Deep','No',50

    SELECT s.*, x.*

    FROM @t s

    CROSS APPLY (

    SELECT EmpNamePart = SUBSTRING(s.EmpName, b, e), b, e

    FROM (

    SELECT

    n.n AS b, -- delimiter at beginning of string

    ISNULL(NULLIF(CHARINDEX(',', s.EmpName, n.n+1), 0), LEN(s.EmpName)+1)-1 AS e -- delimiter at end of string

    FROM

    (SELECT TOP 200 [n] = ROW_NUMBER() OVER(ORDER BY [name]) FROM master.dbo.syscolumns) n -- generates 200 rows where n = 1 to 200

    WHERE SUBSTRING(',' + s.EmpName + ',', n.n, 1) = ','

    AND n < LEN(s.EmpName)

    ) d

    ) x

    ORDER BY s.ID

    Am Getting Ouput Like This

    2Nagu No 20Nagu 14

    4XXX,YYY No 5XXX 13

    4XXX,YYY No 5YYY 57

    5Anil, Rakesh, DeepNo 50 Rakesh, Dee612

    5Anil, Rakesh, DeepNo 50 Deep 1418

    5Anil, Rakesh, DeepNo 50Anil 14

    From There I need to Bring result Rakesh Alone Like this

    Anil, Rakesh, DeepNo 50 Rakesh612

    Even though i have made changes in above code

    SELECT EmpNamePart = SUBSTRING(s.EmpName, b, e-b+1), b, e

    From this situation When send value like 's,Rajesh,Mani'

    Here S -Value get ignored.

    Can you please guide, how can i do this

  • Humble apologies. Revised code attached.

    Declare @t Table

    (

    id int,

    EmpName nvarchar(500),

    status char(5),

    Repair int

    )

    Insert Into @t

    Select 2,'Nagu','No',20 Union All

    Select 4,'XXX,YYY','No',5 Union all

    Select 5,'Anil, Rakesh, Deep','No',50

    SELECT s.*, x.*

    FROM @t s

    CROSS APPLY (

    SELECT EmpNamePart = SUBSTRING(s.EmpName, b, e-b+1),

    SectionBeginning = b,

    SectionEnd = e,

    SectionLength = e-b+1

    FROM (

    SELECT

    n.n AS b, -- delimiter at beginning of string

    ISNULL(NULLIF(CHARINDEX(',', s.EmpName, n.n+1), 0), LEN(s.EmpName)+1)-1 AS e -- delimiter at end of string

    FROM

    (SELECT TOP 200 [n] = ROW_NUMBER() OVER(ORDER BY [name]) FROM master.dbo.syscolumns) n -- generates 200 rows where n = 1 to 200

    WHERE SUBSTRING(',' + s.EmpName + ',', n.n, 1) = ','

    AND n < LEN(s.EmpName)

    ) d

    ) x

    ORDER BY s.ID

    May I suggest that when you are familiar with how the code works, the "teaching aid" stuff is removed? It would look something like this:

    Declare @t Table

    (

    id int,

    EmpName nvarchar(500),

    status char(5),

    Repair int

    )

    Insert Into @t

    Select 2,'Nagu','No',20 Union All

    Select 4,'XXX,YYY','No',5 Union all

    Select 5,'Anil, Rakesh, Deep','No',50

    SELECT s.id, EmpName = LTRIM(x.EmpNamePart), s.Status, s.Repair

    FROM @t s

    CROSS APPLY (

    SELECT EmpNamePart = SUBSTRING(s.EmpName, n.n, ISNULL(NULLIF(CHARINDEX(',', s.EmpName, n.n+1), 0), LEN(s.EmpName)+1)-1-n.n+1)

    FROM (SELECT TOP 200 [n] = ROW_NUMBER() OVER(ORDER BY [name]) FROM master.dbo.syscolumns) n -- create and use a proper table

    WHERE SUBSTRING(',' + s.EmpName + ',', n.n, 1) = ',' AND n < LEN(s.EmpName)

    ) x (EmpNamePart)

    ORDER BY s.ID

    “Write the query the simplest way. If through testing it becomes clear that the performance is inadequate, consider alternative query forms.” - Gail Shaw

    For fast, accurate and documented assistance in answering your questions, please read this article.
    Understanding and using APPLY, (I) and (II) Paul White
    Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden

  • Here is my version, which is 80% based on Chris' logic of using a tally table 🙂

    ;WITH Tens(N) AS

    (

    SELECT 1 UNION ALL

    SELECT 1 UNION ALL

    SELECT 1 UNION ALL

    SELECT 1 UNION ALL

    SELECT 1 UNION ALL

    SELECT 1 UNION ALL

    SELECT 1 UNION ALL

    SELECT 1 UNION ALL

    SELECT 1 UNION ALL

    SELECT 1

    ),

    HUNDREDS AS

    (

    SELECT T1.N FROM TENS T1 CROSS JOIN TENS T2

    ),

    THOUSANDS AS

    (

    SELECT T1.N FROM HUNDREDS T1 CROSS JOIN HUNDREDS T2

    ),

    Numbers AS

    (

    SELECT N = (ROW_NUMBER() OVER(ORDER BY (SELECT 0)) ) FROM THOUSANDS

    )

    SELECT T.*, LTRIM ( SUBSTRING(EmpName, N, (CHARINDEX(',', EmpName + ',', N) - N)) ) AS Item

    FROM Numbers , @t T

    WHERE N < LEN(EmpName) + 2

    AND SUBSTRING(',' + EmpName , N, 1) = ','

    ORDER BY id

    ~Edit : Fixed leading spaces from the split string.

  • And i presume your EmpName does not have trailin/leading commas.. Else we will have to use another method.

  • ColdCoffee (10/21/2010)


    And i presume your EmpName does not have trailin/leading commas.. Else we will have to use another method.

    There's a trick for that...put them in then

    REPLACE(',' + EmpName + ',',',,',',')

    “Write the query the simplest way. If through testing it becomes clear that the performance is inadequate, consider alternative query forms.” - Gail Shaw

    For fast, accurate and documented assistance in answering your questions, please read this article.
    Understanding and using APPLY, (I) and (II) Paul White
    Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden

  • And i must admit that my code is purely what the DelimitedSplit8K (function from Jeff Moden on splitting delimited strings) does!! So toss ur credits to Jeff Moden and the people behind that awesome splitter..

  • Chris Morris-439714 (10/21/2010)


    ColdCoffee (10/21/2010)


    And i presume your EmpName does not have trailin/leading commas.. Else we will have to use another method.

    There's a trick for that...put them in then

    REPLACE(',' + EmpName + ',',',,',',')

    fantastic thought CM, but there is a catch here...

    Assume the string is like this

    ',an,empty,space,comes,between,this,and, ,this,'

    Then the REPLACE will collapse the string... correct me if am wrong..

  • What about this?

    select reverse(stuff( reverse(stuff(@string,1,1,'')) ,1,1,''))

    Ugly, but still 😛

  • Wiht the Chris idea on the cross apply and my previous split function that used for other perpose

    i have written like this :

    Declare @t Table

    (

    id int,

    EmpName nvarchar(500),

    status char(5),

    Repair int

    )

    Insert Into @t

    Select 1,'Arun,Balu','Yes',25 Union All

    Select 2,'Nagu','No',20 Union All

    Select 3,'Mani','No',45 Union All

    Select 4,'XXX,YYY','No',5 union all

    Select 5,'Anil, Rakesh, Deep','No',50

    select t1.id,t1.Empname,t2.id,t2.Param from @t as t1

    Cross apply dbo.Fn_Split(t1.id,t1.Empname,',') as t2

    and the Sql Function is like

    -- Split Function

    -- i am passing id which can be your any column values

    If Exists (Select Name from Sysobjects where name='Fn_Split' And xtype='TF')

    Begin

    Drop function dbo.Fn_Split

    End

    Go

    CREATE FUNCTION dbo.Fn_Split(@id int,@RepParam nvarchar(4000), @Delim char(1)= ',')

    RETURNS @Values TABLE (id int,Param varchar(100))AS

    BEGIN

    DECLARE @chrind INT

    DECLARE @Piece nvarchar(4000)

    SELECT @chrind = 1

    WHILE @chrind > 0

    BEGIN

    SELECT @chrind = CHARINDEX(@Delim,@RepParam)

    IF @chrind > 0

    SELECT @Piece = LEFT(@RepParam,@chrind - 1)

    ELSE

    SELECT @Piece = @RepParam

    INSERT @Values(id,Param) VALUES(@id,@Piece)

    SELECT @RepParam = RIGHT(@RepParam,LEN(@RepParam) - @chrind)

    IF LEN(@RepParam) = 0 BREAK

    END

    RETURN

    END

    GO

    1Arun,Balu1Arun

    1Arun,Balu1Balu

    2Nagu2Nagu

    3Mani3Mani

    4XXX,YYY4XXX

    4XXX,YYY4YYY

    5Anil, Rakesh, Deep5Anil

    5Anil, Rakesh, Deep5 Rakesh

    5Anil, Rakesh, Deep5 Deep

    Please let me know if i am wrong in any way

Viewing 15 posts - 1 through 15 (of 17 total)

You must be logged in to reply to this topic. Login to reply