Search code examples
sqlsql-server-2008pivotpivot-tableunpivot

SQL Removing a filter from an unpivot table


I have this unpivot table and I wish to remove the filter that is applied to it.

DECLARE @colsPivot AS NVARCHAR(MAX),
    @colsUnpivot as NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)



select @colsPivot = STUFF((SELECT distinct ',' + QUOTENAME(year(EcoDate)) 
                    from PhdRpt.RptCaseEco
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsUnpivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('PhdRpt.RptCaseEco') 
         and C.name Like 'Net%'
         for xml path('')), 1, 1, '')


set @query 
  = 'select *
      from
      (
        select reportruncaseid, year(Ecodate) as EcoYear, val, col
        from phdrpt.rptcaseeco

        unpivot
        (
          val
          for col in ('+ @colsUnpivot +')
        ) u
      ) x1
      pivot
      (
        max(val)
        for ecoyear in ('+ @colspivot +')

      ) p ORDER BY reportruncaseid'


exec(@query)

This table worked before because all the columns had a prefix of "Net" but now there are other columns that are being filtered out because they do not begin with "Net". I tried to remove --- and C.name Like 'Net%' --- but I keep getting these errors:

Msg 8167, Level 16, State 1, Line 10 The type of column "EcoDate" conflicts with the type of other columns specified in the UNPIVOT list.
Msg 207, Level 16, State 1, Line 4 Invalid column name 'reportruncaseid'.
Msg 207, Level 16, State 1, Line 4 Invalid column name 'Ecodate'.

Here is what the table looks like
Table


Solution

  • The filter to get the list of columns to UNPIVOT can be removed but if there are columns that you do not want to UNPIVOT then you will need to exclude them:

    select @colsUnpivot = stuff((select ','+quotename(C.name)
             from sys.columns as C
             where C.object_id = object_id('PhdRpt.RptCaseEco') 
             and C.name not in ('reportruncaseid', 'Ecodate')
             for xml path('')), 1, 1, '')
    

    This will return all of the columns to unpivot, except reportruncaseid and Ecodate (or other columns you do not want unpivoted). So the full query will be:

    DECLARE @colsPivot AS NVARCHAR(MAX),
        @colsUnpivot as NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX)
    
    select @colsPivot = STUFF((SELECT distinct ',' + QUOTENAME(year(EcoDate)) 
                        from PhdRpt.RptCaseEco
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')
    
    select @colsUnpivot = stuff((select ','+quotename(C.name)
             from sys.columns as C
             where C.object_id = object_id('PhdRpt.RptCaseEco') 
             and C.name not in ('reportruncaseid', 'Ecodate')
             for xml path('')), 1, 1, '')
    
    set @query 
      = 'select *
          from
          (
            select reportruncaseid, year(Ecodate) as EcoYear, val, col
            from phdrpt.rptcaseeco
    
            unpivot
            (
              val
              for col in ('+ @colsUnpivot +')
            ) u
          ) x1
          pivot
          (
            max(val)
            for ecoyear in ('+ @colspivot +')
    
          ) p ORDER BY reportruncaseid'
    
    exec(@query);
    

    Also if you have columns that are different datatypes, then you will have to cast them to the same datatype prior to applying the unpivot.