Split a single Record into multiple lines

  • Hi there,

    I am hoping someone here can help me with a problem I have ran into. Below is the data, bascially each record has upto 8 sets of item/qty/value. (I have shown just 3 for convenience).

    No Item1|Qty1|Value1 | Item2 | Qty2 | Value2 | Item2 | Qty2 | Value2

    1 ABC 3 10.00 DEF 4 20.00 GHI 6 30.00

    2 IEO 10 43.00 WER 18 12.00

    The requirement is to split each set Item/Qty/Value on to its own line. Essentially it should look like this :

    1 ABC 3 10.00

    1 DEF 4 20.00

    1 GHI 6 30.00

    2 IEO 10 43.00

    2 WER 18 12.00

    I intentionally skipped the 3rd (item/qty/value) set from 2nd record as it is possible it could be empty.

    I would appreciate any feedback on how to resolve this issue. BTW, I am using SQL2005.

    When I have this straigthened , it will serve as my dataset for a SSRS report.

    Thanks in advance.

    TP

  • tony.pinto (11/12/2009)


    Hi there,

    I am hoping someone here can help me with a problem I have ran into. Below is the data, bascially each record has upto 8 sets of item/qty/value. (I have shown just 3 for convenience).

    No Item1|Qty1|Value1 | Item2 | Qty2 | Value2 | Item2 | Qty2 | Value2

    1 ABC 3 10.00 DEF 4 20.00 GHI 6 30.00

    2 IEO 10 43.00 WER 18 12.00

    The requirement is to split each set Item/Qty/Value on to its own line. Essentially it should look like this :

    1 ABC 3 10.00

    1 DEF 4 20.00

    1 GHI 6 30.00

    2 IEO 10 43.00

    2 WER 18 12.00

    I intentionally skipped the 3rd (item/qty/value) set from 2nd record as it is possible it could be empty.

    I would appreciate any feedback on how to resolve this issue. BTW, I am using SQL2005.

    When I have this straigthened , it will serve as my dataset for a SSRS report.

    Thanks in advance.

    TP

    Are these in a table or in a file? Also, you'd get a lot more bites on your question if you'd post the data in a readily consumable format. Please see the first link in my signature below for how to do that.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.
    "Change is inevitable... change for the better is not".

    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)
    Intro to Tally Tables and Functions

  • There was lately a thread on an almost similar problem. Take a look at .

    Peter

  • Had your table been normalised ,u wouldn't have run into this problem.

    One way that i can think of is by using a cursor on your table.

    Create a cursor on your table and get the 10 column values into variables.

    Create a temporary table with 4 columns n insert the required values into it.

    Finally select * from the temporary table.

    Can't think of a better solution to it.

  • For Convenience, i have also taken 3 sets for Item/Qty/Value..Is this the solution you are looking for?

    I have created test table with some dummy data...

    use tempdb

    if object_id('tempdb..#testsplit') is not null

    drop table #testsplit

    create table #testsplit(SNO int,

    Item1 varchar(10),qty1 int,value1 int,

    Item2 varchar(10),qty2 int,value2 int,

    Item3 varchar(10),qty3 int,value3 int)

    insert into #testsplit values(1,'a',10,100,'b',20,200,'c',30,300)

    insert into #testsplit values(2,'d',40,400,'e',50,500,'f',60,600)

    insert into #testsplit values(3,'g',70,700,'h',80,800,'i',90,900)

    select SNo,Item1,Qty1,Value1 from #testsplit

    union all

    select SNo,Item2,Qty2,Value2 from #testsplit

    union all

    select SNo,Item3,Qty3,Value3 from #testsplit

    order by SNo

  • This will work. It's so amazing, what seemed to me so huge you made it so easy 🙂

    Thanks Much,

    TP

  • You welcome..

  • Although the solution provided by Jus is simple and straight forward, it might lead to a performance problem. With eight triples of columns it leads to eight table scan. The thread I mentioned in my previous post was just addressing that problem. A faster solution looks like the following (thanks Jus for providing the initial test data):

    use tempdb

    if object_id('tempdb..#testsplit') is not null

    drop table #testsplit

    create table #testsplit

    (

    SNO int primary key,

    Item1 varchar(10),qty1 int,value1 int,

    Item2 varchar(10),qty2 int,value2 int,

    Item3 varchar(10),qty3 int,value3 int,

    Item4 varchar(10),qty4 int,value4 int,

    Item5 varchar(10),qty5 int,value5 int,

    Item6 varchar(10),qty6 int,value6 int,

    Item7 varchar(10),qty7 int,value7 int,

    Item8 varchar(10),qty8 int,value8 int

    )

    insert into #testsplit(SNO,

    Item1, qty1, value1,

    Item2, qty2, value2,

    Item3, qty3, value3,

    Item4, qty4, value4,

    Item5, qty5, value5,

    Item6, qty6, value6

    )

    values(1,'a',10,100,'b',20,200,'c',30,300,'x',15,125,'y',63,133,'z',31,255)

    insert into #testsplit(SNO,

    Item1, qty1, value1,

    Item2, qty2, value2,

    Item3, qty3, value3,

    Item4, qty4, value4,

    Item5, qty5, value5

    ) values(2,'d',40,400,'e',50,500,'f',60,600,'u',100,750,'v',75,900)

    insert into #testsplit(SNO,

    Item1, qty1, value1,

    Item2, qty2, value2,

    Item3, qty3, value3

    ) values(3,'g',70,700,'h',80,800,'i',90,900)

    select

    u.SNo, n.Item, n.qty, n.Value

    from

    #testsplit u

    cross apply

    (

    select Item1 as Item, qty1 as qty, Value1 as Value where Item1 is not null and qty1 is not null and Value1 is not null

    union all

    select Item2 as Item, qty2 as qty, Value2 as Value where Item2 is not null and qty2 is not null and Value2 is not null

    union all

    select Item3 as Item, qty3 as qty, Value3 as Value where Item3 is not null and qty3 is not null and Value3 is not null

    union all

    select Item4 as Item, qty4 as qty, Value4 as Value where Item4 is not null and qty4 is not null and Value4 is not null

    union all

    select Item5 as Item, qty5 as qty, Value5 as Value where Item5 is not null and qty5 is not null and Value5 is not null

    union all

    select Item6 as Item, qty6 as qty, Value6 as Value where Item6 is not null and qty6 is not null and Value6 is not null

    union all

    select Item7 as Item, qty7 as qty, Value7 as Value where Item7 is not null and qty7 is not null and Value7 is not null

    union all

    select Item8 as Item, qty8 as qty, Value8 as Value where Item8 is not null and qty8 is not null and Value8 is not null

    ) n

    order by

    1

    It scans the table just once and splits up every row into at most eight triples.

    Peter

  • I got you..Thanks much...

    Jus

  • Perfect !! I tried both and I do see a difference in performance.

    Thanks for the input much appreciated.

    Thanks.

    Tony

  • Just a tiny change to Peters excellent sample:

    I moved the WHERE clause from the UNION ALL part to the outer part of the query.

    Performance seems to be the same (query plan shows that the filter part is at a different position).

    It helps readability, I think. But I'm not sure if it will scale much different than Peters original solution.

    Again, Peter: excellent solution!!

    cross apply

    (

    select Item1 as Item, qty1 as qty, Value1 as Value

    union all

    select Item2 as Item, qty2 as qty, Value2 as Value

    union all

    select Item3 as Item, qty3 as qty, Value3 as Value

    union all

    select Item4 as Item, qty4 as qty, Value4 as Value

    union all

    select Item5 as Item, qty5 as qty, Value5 as Value

    union all

    select Item6 as Item, qty6 as qty, Value6 as Value

    union all

    select Item7 as Item, qty7 as qty, Value7 as Value

    union all

    select Item8 as Item, qty8 as qty, Value8 as Value

    ) n

    WHERE ISNULL(n.qty + n.Value,Item) IS NOT NULL

    order by

    1



    Lutz
    A pessimist is an optimist with experience.

    How to get fast answers to your question[/url]
    How to post performance related questions[/url]
    Links for Tally Table [/url] , Cross Tabs [/url] and Dynamic Cross Tabs [/url], Delimited Split Function[/url]

  • I did that test also. It requires less coding but, based on the 3 rows input, there are less rows generated within the cross apply to join with if you put the null tests inside the cross apply. With 3 rows of input it's hard to measure any difference in performance. I leave it as an exercise to the OP to prove otherwise.

  • Peter Brinkhaus (11/13/2009)


    I did that test also. It requires less coding but, based on the 3 rows input, there are less rows generated within the cross apply to join with if you put the null tests inside the cross apply. With 3 rows of input it's hard to measure any difference in performance. I leave it as an exercise to the OP to prove otherwise.

    I absolutely agree.

    Just a thought: do you know if there's already an article describing the technique you used? If not I think you should write one... What do you think?



    Lutz
    A pessimist is an optimist with experience.

    How to get fast answers to your question[/url]
    How to post performance related questions[/url]
    Links for Tally Table [/url] , Cross Tabs [/url] and Dynamic Cross Tabs [/url], Delimited Split Function[/url]

  • lmu92 (11/13/2009)


    Peter Brinkhaus (11/13/2009)


    I did that test also. It requires less coding but, based on the 3 rows input, there are less rows generated within the cross apply to join with if you put the null tests inside the cross apply. With 3 rows of input it's hard to measure any difference in performance. I leave it as an exercise to the OP to prove otherwise.

    I absolutely agree.

    Just a thought: do you know if there's already an article describing the technique you used? If not I think you should write one... What do you think?

    In the thread http://qa.sqlservercentral.com/Forums/Topic809640-338-1.aspx I mentioned before there was already another person suggesting to write an article about this. So for now I leave it up to him.

    Peter

Viewing 14 posts - 1 through 13 (of 13 total)

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