9

I have a table that looks similar to this here:

SetId       AppCode       AppEventId       EventId       FieldId       ValueData
2012/2013     1000         361616             16            1            UNI     
2012/2013     1000         361616             16            2            Isolation
2012/2013     1000         361616             16            3            DN
2012/2013     1050         378194             16            1            BUL
2012/2013     1050         378194             16            2            Isolation
2012/2013     1050         378194             16            3            RD

I would like to able to combine all that data when they have the same AppCode.

Which would look like this:

SetId       AppCode       AppEventId       EventId       ValueData1      ValueData2      ValueData3
2012/2013     1000         361616             16            UNI            Isolation        DN
2012/2013     1050         378194             16            BUL            Isolation        RD
5
  • 3
    PIVOT Is the answer. Show us what have you Tried. Commented Apr 17, 2013 at 9:40
  • Hi, I believe your table does not follow normalization rules. you should reconsider your table structure first. Commented Apr 17, 2013 at 9:42
  • 2
    Thanks Luv i'll look into PIVOT. Commented Apr 17, 2013 at 9:57
  • Allan - unfortunately I can't amend the table structure. Commented Apr 17, 2013 at 9:58
  • are there only 3 fieldId's? or does this also have to be flexible? Commented Apr 17, 2013 at 10:00

4 Answers 4

19

Try this

  SELECT SetId, AppCode, AppEventId, EventId 
  ,max(CASE WHEN FieldId = 1 THEN ValueData END) AS ValueData1
  ,max(CASE WHEN FieldId = 2 THEN ValueData END) AS ValueData2
  ,max(CASE WHEN FieldId = 3 THEN ValueData END) AS ValueData3
   FROM Table_Name 
   GROUP BY SetId,AppCode,AppEventId,EventId 
Sign up to request clarification or add additional context in comments.

2 Comments

@bvr the same doesn't work for me with sql server 2008.
I think END must be inside bracket : max(CASE WHEN FieldId = 1 THEN ValueData END) AS ValueData1
7

This can be done by applying the PIVOT function which was made available starting in SQL Server 2005.

If you have a known or set number of values that you want to transform into columns, then ou can hard-code the query:

select setid, appcode, appeventid,
  eventid,
  ValueData1, ValueData2, ValueData3
from
(
  select setid, appcode, appeventid,
    eventid,
    'ValueData'+cast(FieldId as varchar(10)) FieldId, 
    ValueData
  from yt
) d
pivot
(
  max(ValueData)
  for FieldId in (ValueData1, ValueData2, ValueData3)
) piv;

See SQL Fiddle with Demo.

But if you have an unknown number of values, then you will need to use dynamic SQL:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME('ValueData'+cast(FieldId as varchar(10))) 
                    from yt
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT setid, appcode, appeventid,
                  eventid,' + @cols + ' 
            from 
            (
                select setid, appcode, appeventid,
                  eventid,
                  ''ValueData''+cast(FieldId as varchar(10)) FieldId, 
                  ValueData
                from yt
            ) x
            pivot 
            (
                max(ValueData)
                for FieldId in (' + @cols + ')
            ) p '

execute(@query);

See SQL Fiddle with Demo. Both queries give the same result:

|     SETID | APPCODE | APPEVENTID | EVENTID | VALUEDATA1 | VALUEDATA2 | VALUEDATA3 |
-------------------------------------------------------------------------------------
| 2012/2013 |    1000 |     361616 |      16 |        UNI |  Isolation |         DN |
| 2012/2013 |    1050 |     378194 |      16 |        BUL |  Isolation |         RD |

Comments

2

UPDATE:

Improve answer -

DECLARE @temp TABLE
(
        SetId VARCHAR(9)       
      , AppCode CHAR(4)      
      , AppEventId INT      
      , EventId INT      
      , FieldId TINYINT      
      , ValueData VARCHAR(50)
)

INSERT INTO @temp (SetId, AppCode, AppEventId, EventId, FieldId, ValueData)
VALUES 
    ('2012/2013',     '1000',         361616,             16,            1,            'UNI'),    
    ('2012/2013',     '1000',         361616,             16,            2,            'Isolation'),
    ('2012/2013',     '1000',         361616,             16,            3,            'DN'),
    ('2012/2013',     '1050',         378194,             16,            1,            'BUL'),
    ('2012/2013',     '1050',         378194,             16,            2,            'Isolation'),
    ('2012/2013',     '1050',         378194,             16,            3,            'RD')

;WITH tbl AS 
(
    SELECT  
            PK = t.SetId + t.AppCode + CAST(AppEventId AS VARCHAR(10)) + CAST(EventId AS VARCHAR(5))
          , t.SetId
          , t.AppCode
          , t.AppEventId
          , t.EventId
          , t.FieldId
          , t.ValueData
    FROM @temp t
) 
SELECT DISTINCT 
      t.SetId
    , t.AppCode
    , t.AppEventId
    , t.EventId
    , t2.ValueData
    , t3.ValueData
    , t4.ValueData
FROM tbl t
JOIN tbl t2 ON t.PK = t2.PK AND t2.FieldId = 1
JOIN tbl t3 ON t.PK = t3.PK AND t3.FieldId = 2
JOIN tbl t4 ON t.PK = t4.PK AND t4.FieldId = 3

Not elegant, but it works -

DECLARE @temp TABLE
(
        SetId VARCHAR(9)       
      , AppCode CHAR(4)      
      , AppEventId INT      
      , EventId INT      
      , FieldId TINYINT      
      , ValueData VARCHAR(50)
)

INSERT INTO @temp (SetId, AppCode, AppEventId, EventId, FieldId, ValueData)
VALUES 
    ('2012/2013',     '1000',         361616,             16,            1,            'UNI'),    
    ('2012/2013',     '1000',         361616,             16,            2,            'Isolation'),
    ('2012/2013',     '1000',         361616,             16,            3,            'DN'),
    ('2012/2013',     '1050',         378194,             16,            1,            'BUL'),
    ('2012/2013',     '1050',         378194,             16,            2,            'Isolation'),
    ('2012/2013',     '1050',         378194,             16,            3,            'RD')

SELECT  t.SetId
    ,   t.AppCode
    ,   t.AppEventId
    ,   t.EventId
    ,   t2.ValueData
    ,   t3.ValueData
    ,   t4.ValueData
FROM (
    SELECT  
          t.SetId
        , t.AppCode
        , t.AppEventId
        , t.EventId
        , FieldId1 = MAX(CASE WHEN t.FieldId = 1 THEN t.FieldId END)
        , FieldId2 = MAX(CASE WHEN t.FieldId = 2 THEN t.FieldId END)
        , FieldId3 = MAX(CASE WHEN t.FieldId = 3 THEN t.FieldId END)
    FROM @temp t
    GROUP BY 
          t.SetId
        , t.AppCode
        , t.AppEventId
        , t.EventId
) t
JOIN @temp t2 ON t.SetId = t2.SetId
        AND t.AppCode = t2.AppCode
        AND t.AppEventId = t2.AppEventId
        AND t.EventId = t2.EventId
        AND t2.FieldId = 1
JOIN @temp t3 ON t.SetId = t3.SetId
        AND t.AppCode = t3.AppCode
        AND t.AppEventId = t3.AppEventId
        AND t.EventId = t3.EventId
        AND t3.FieldId = 2
JOIN @temp t4 ON t.SetId = t4.SetId
        AND t.AppCode = t4.AppCode
        AND t.AppEventId = t4.AppEventId
        AND t.EventId = t4.EventId
        AND t4.FieldId = 3

Comments

0

You can get multiple rows in a single row using this stored procedure:

CREATE PROCEDURE GetMultipleRowsAsSingleRow @EMP_NUMBER VARCHAR(10)
AS
    DECLARE @tmp varchar(MAX)
    SET @tmp = ''

    SELECT
        EMP_NUMBER, TYPE_ID  
    FROM
        tableNumberOne 
    WHERE 
        EMP_NUMBER = @EMP_NUMBER
 
    SELECT SUBSTRING(@tmp, 0, LEN(@tmp))
GO;

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.