Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transpose SQL columns to rows

I have the table below and would like to transpose this in SQL, I have tried using sql PIVOT but I am getting nowhere. Any help is much appreciated.

CID ActID   ActType         ActDate
1   10      Assessment      2017-08-09
1   11      StartOfPOC      2017-11-01
1   22      POC1            2017-11-03
1   22      POC2            2017-11-03
2   44      Report          2017-11-03
2   44      Planning        2017-11-03
3   66      Assessment      2017-11-06
3   66      POC1            2017-11-06
3   77      EndOfPOC        2017-11-06

I would like to transpose this table to the below

CID     ActType1    ActDate1    ActType2    ActDate2    ActType3    ActDate3    ActType4    ActDate4    ActType4    ActDate4        
1       Assessment  2017-08-09  StartOfPOC  2017-11-01  POC1        2017-11-03  POC2        2017-11-03
2       POC1        2017-11-03  Planning    2017-11-03
3       Assessment  2017-11-06  POC1        2017-11-06  EndOfPOC    2017-11-06

Below is what i have but want to improve from here.

SELECT * FROM (
  Select
     CID
    ,ActID   
    ,ActType         
    ,ActDate
  from #tbl r
  where r.ActType in ('Assessment','Start of POC','POC1','POC2','Report','Planning','EndOfPOC')  
) x
PIVOT( MAX(ActDate)
FOR ActType IN (
     [Assessment]
    ,[Start of POC]
    ,[POC1]
    ,[POC2]
    ,[Reporting]
    ,[Planning]
    ,[End of POC]
    )
) p

Thanks

like image 371
jk1844 Avatar asked Mar 05 '23 08:03

jk1844


1 Answers

Rather than PIVOT, I would use a Conditional Aggregation in concert with Row_Number()

Example

Select CID
      ,AcctType1 = max(case when RN = 1 then ActType end)
      ,AcctDate1 = max(case when RN = 1 then ActDate end)
      ,AcctType2 = max(case when RN = 2 then ActType end)
      ,AcctDate2 = max(case when RN = 2 then ActDate end)
      ,AcctType3 = max(case when RN = 3 then ActType end)
      ,AcctDate3 = max(case when RN = 3 then ActDate end)
      ,AcctType4 = max(case when RN = 4 then ActType end)
      ,AcctDate4 = max(case when RN = 4 then ActDate end)
From (
        Select * 
              ,RN= Row_Number() over (Partition By CID Order by ActDate)
         From YourTable
     ) A
 Group By CID

Returns

enter image description here

like image 132
John Cappelletti Avatar answered Mar 07 '23 11:03

John Cappelletti