Pivot, Unpivot and Cross Apply !!!! Nothing seems to work

  • Consider the below T-SQL

    CREATE TABLE Temp10(Source nvarchar(50),Target nvarchar(50),Property1 int,Property2 int,

    Property3 int,Property4 decimal,Property5 nvarchar(100),Property6 nvarchar(50))

    INSERT INTO Temp10 values('A','DEF',10,8,20,12.34,'Good','Bad')

    INSERT INTO Temp10 values('A','GKL',2,14,0,20.4,'Bad','Good')

    INSERT INTO Temp10 values('A','MNO',4,4,60,100.6,'Excellent','Good')

    INSERT INTO Temp10 values('B','ABC',3,7,20,10.6,'Good','Good')

    INSERT INTO Temp10 values('B','DEF',9,3,40,70.6,'Bad','Bad')

    INSERT INTO Temp10 values('C','XYZ',10,7,85,30.6,'Excellent','Excellent')

    I want the output as follow

    NewSequenceNewTargetOption1Option2Option3

    SourceADEFGKLMNO

    Property11024

    Property28144

    Property320060

    Property41220101

    Property5GoodBadExcellent

    Property6BadGoodGood

    Source BABCDEF

    Property139

    Property273

    Property32040

    Property41171

    Property5GoodBad

    Property6GoodBad

    Source CXYZ

    Property110

    Property27

    Property385

    Property431

    Property5Excellent

    Property6Excellent

    I have tried all the options.. which include pivot,unpivot, cross apply 🙁 .... nothing seems to work.... :angry:

    Any help on this would be highly appreciated......

    Thanks.

  • I'm not sure why are you doing this on SQL Server, it might be better on the front-end.

    However, if you really need to format your output like this on SQL Server, this should do it.

    WITH CTE AS(

    SELECT *, ROW_NUMBER() OVER( PARTITION BY Source ORDER BY Target) rn

    FROM #Temp10)

    SELECT Newsequence,

    CASE WHEN Newsequence = 'Source' THEN Source ELSE '' END Source,

    MAX( CASE WHEN rn = 1 THEN Value ELSE '' END) Option1,

    MAX( CASE WHEN rn = 2 THEN Value ELSE '' END) Option2,

    MAX( CASE WHEN rn = 3 THEN Value ELSE '' END) Option3

    FROM CTE

    CROSS APPLY (VALUES('Source', CAST( Target AS nvarchar(100))),

    ('Property1', CAST( Property1 AS nvarchar(100))),

    ('Property2', CAST( Property2 AS nvarchar(100))),

    ('Property3', CAST( Property3 AS nvarchar(100))),

    ('Property4', CAST( Property4 AS nvarchar(100))),

    ('Property5', CAST( Property5 AS nvarchar(100))),

    ('Property6', CAST( Property6 AS nvarchar(100)))

    )x(Newsequence, Value)

    GROUP BY Newsequence,

    Source

    ORDER BY CTE.Source,

    CASE WHEN Newsequence = 'Source' THEN 'a' ELSE Newsequence END;

    Luis C.
    General Disclaimer:
    Are you seriously taking the advice and code from someone from the internet without testing it? Do you at least understand it? Or can it easily kill your server?

    How to post data/code on a forum to get the best help: Option 1 / Option 2
  • Thank you very much Luis for the reply. Now i have being trying to work around your query since yesterday but it does not seem to be working.I would appreciate if you could help me with this.

    In the actual scenarion i did not have only 3 distinct entries in source column. They can vary. I tried to accomodate that change in the following way

    DECLARE @CNT INT

    WITH CTE AS(

    SELECT *, ROW_NUMBER() OVER( PARTITION BY Source ORDER BY Target) rn

    FROM Temp10)

    SELECT @CNT=COUNT(DISTINCT Source) FROM Temp10

    SELECT

    Newsequence,

    CASE WHEN Newsequence = 'Source' THEN Source ELSE '' END Source,

    MAX( CASE WHEN rn = @CNT then Value else '' end) 'option' + convert(nvarchar(5),@cnt)

    --MAX( CASE WHEN rn = 1 THEN Value ELSE '' END) Option1,

    --MAX( CASE WHEN rn = 2 THEN Value ELSE '' END) Option2,

    --MAX( CASE WHEN rn = 3 THEN Value ELSE '' END) Option3

    FROM CTE

    CROSS APPLY (VALUES('Source', CAST( Target AS nvarchar(100))),

    ('Property1', CAST( Property1 AS nvarchar(100))),

    ('Property2', CAST( Property2 AS nvarchar(100))),

    ('Property3', CAST( Property3 AS nvarchar(100))),

    ('Property4', CAST( Property4 AS nvarchar(100))),

    ('Property5', CAST( Property5 AS nvarchar(100))),

    ('Property6', CAST( Property6 AS nvarchar(100)))

    )x(Newsequence, Value)

    GROUP BY Newsequence,

    Source

    ORDER BY CTE.Source,

    CASE WHEN Newsequence = 'Source' THEN 'a' ELSE Newsequence END;

    Which is shows syntax error. Could you please help me with this.

  • I corrected your syntax. Don't forget to place semicolons at the end of your statements or you'll get another error with the with statement.

    WITH data AS(

    SELECT *, ROW_NUMBER() OVER( PARTITION BY Source ORDER BY Target) rn

    FROM temp10),

    cnt as (

    select COUNT(DISTINCT Source) as cnt from temp10

    ),

    cte as (

    select * from data, cnt

    )

    SELECT

    Newsequence,

    CASE WHEN Newsequence = 'Source' THEN Source ELSE '' END Source,

    MAX( CASE WHEN rn = cnt then Value else '' end) + 'option' + max(convert(nvarchar(5),cnt)),

    MAX( CASE WHEN rn = 1 THEN Value ELSE '' END) Option1,

    MAX( CASE WHEN rn = 2 THEN Value ELSE '' END) Option2,

    MAX( CASE WHEN rn = 3 THEN Value ELSE '' END) Option3

    FROM CTE

    CROSS APPLY (VALUES('Source', CAST( [Target] AS nvarchar(100))),

    ('Property1', CAST( Property1 AS nvarchar(100))),

    ('Property2', CAST( Property2 AS nvarchar(100))),

    ('Property3', CAST( Property3 AS nvarchar(100))),

    ('Property4', CAST( Property4 AS nvarchar(100))),

    ('Property5', CAST( Property5 AS nvarchar(100))),

    ('Property6', CAST( Property6 AS nvarchar(100)))

    )x(Newsequence, Value)

    GROUP BY Newsequence,

    Source

    ORDER BY CTE.Source,

    CASE WHEN Newsequence = 'Source' THEN 'a' ELSE Newsequence END;



    Dan Guzman - Not the MVP (7/22/2010)
    All questions have to be prefaced by Server version and 'according to MS Docs' or 'my own personal opinion based on how much detail I felt like digging into at the time.'

  • Thanks once again for the reply....

    But what i am trying to do is, i want to loop through

    MAX( CASE WHEN rn = 1 THEN Value ELSE '' END) Option1,

    MAX( CASE WHEN rn = 2 THEN Value ELSE '' END) Option2,

    MAX( CASE WHEN rn = 3 THEN Value ELSE '' END) Option3

    For OptionN number of times where N is

    select max(MaxNum)

    from(

    SELECT source,(count((Target))) as MaxNum

    FROM Temp10

    group by Source

    )D

    I tried using a CTE within a select which i guess is not premissible, is there any other way to go at it

  • In this article, you can find how to do it dynamic. But I still recommend to do all this formatting outside of SQL server.

    http://www.sqlservercentral.com/articles/Crosstab/65048/

    Luis C.
    General Disclaimer:
    Are you seriously taking the advice and code from someone from the internet without testing it? Do you at least understand it? Or can it easily kill your server?

    How to post data/code on a forum to get the best help: Option 1 / Option 2
  • What Luis is hinting at is that unless you write code to create the sql statement you want to run each time, the number of columns in your output will always be the same.

    You have a choice, you can chose some maximum nunber of culumns you care about, and write your code to handle up-to that number of columns, or you can take the more-difficult route of dynamic sql as outlined in that article among others.

    -a.



    Dan Guzman - Not the MVP (7/22/2010)
    All questions have to be prefaced by Server version and 'according to MS Docs' or 'my own personal opinion based on how much detail I felt like digging into at the time.'

Viewing 7 posts - 1 through 6 (of 6 total)

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