2012-09-14 23 views
5

Hola Tengo la siguiente tabla y quiero hacer pivotar el EcoYear para que esté en la parte superior, pero no hay una cantidad establecida de años y los años podrían comenzar en cualquier momento. Además, los diferentes casos tendrán diferentes años iniciales, así que lo necesito para rellenar 0 en lugar de nulo.
Tabla dinámica de Pivot en SQL Server

CaseID EcoYear NetInv NetOil NetGas 
38755 2006 123  2154   525 
38755 2007 123  2154   525 
38755 2008 123  2154   525 
38755 2009 123  2154   525 
38755 2010 123  2154   525 
38755 2011 123  2154   525 
38755 2012 123  2154   525 
38755 2013 123  2154   525 
38755 2014 123  2154   525 
38755 2015 123  2154   525 
38755 2016 123  2154   525 
38755 2017 123  2154   525 
38755 2018 123  2154   525 
38755 2019 123  2154   525 
38755 2020 123  2154   525 

necesito la mesa para tener este aspecto:

CaseID Item 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 
38755 NetInv 
38755 NetOil 
38755 NetGas 

Esto se hizo originalmente con acceso utilizando una tabla de referencias cruzadas.

+0

Respuesta corta - No hagas esto en SQL Server, hazlo en cualquier aplicación que estés usando para presentar los datos. –

+0

Mi tarea es hacerlo en SQL Server porque los desarrolladores no pueden usar Access en la nueva versión. ¡Gracias! –

+0

Una búsqueda de "dynamic sql" "Pivot" debería mostrarle cómo hacerlo. Pruébalo y vuelve con cualquier problema – podiluska

Respuesta

14

Esto se puede hacer en el servidor sql utilizando un UNPIVOT y luego un PIVOT. Una versión estática es donde se sabe que las columnas para transformar:

select * 
from 
(
    select CaseId, EcoYear, val, item 
    from yourtable 
    unpivot 
    (
    val 
    for Item in (NetInv, NetOil, NetGas) 
)u 
) x 
pivot 
(
    max(val) 
    for ecoyear in ([2006], [2007], [2008], [2009], [2010], [2011], 
       [2012], [2013], [2014], [2015], [2016], [2017], 
       [2018], [2019], [2020]) 
) p 

ve SQL Fiddle with Demo

una versión dinámica determinará los registros de ejecución:

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

select @colsPivot = STUFF((SELECT distinct ',' + QUOTENAME(EcoYear) 
        from yourtable 
      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('yourtable') and 
       C.name LIKE 'Net%' 
     for xml path('')), 1, 1, '') 


set @query 
    = 'select * 
     from 
     (
     select caseid, ecoyear, val, col 
     from yourtable 
     unpivot 
     (
      val 
      for col in ('+ @colsunpivot +') 
     ) u 
    ) x1 
     pivot 
     (
     max(val) 
     for ecoyear in ('+ @colspivot +') 
    ) p' 

exec(@query) 

ve SQL Fiddle with Demo

+0

Gracias. Esto es exactamente lo que necesitaba hacer. ¿Esta versión dinámica podrá agregar columnas adicionales para otros casos que podrían comenzar en una fecha posterior a 2006? Por ejemplo, si comenzó en 2008 saldría hasta 2022, pero para las columnas con 2006 y 2007 solo mostrará ceros. Y gracias por tu ayuda. ¡Utilizaré esto como base para mis otros informes! –

+0

@RolandP agregará columnas para los campos que tenga en su 'EcoYear', luego puede restringir los años según sea necesario. – Taryn