Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Colonne dinamiche - SQL Server - Mesi come colonne

I tuoi dati sono già convertiti, ma devono essere spostati a un livello diverso. Penso che il modo migliore per gestirlo sia prima di annullare il pivot, quindi gestire il livello di pivot corretto in secondo luogo.

Passaggio 1:annulla il pivot

È possibile utilizzare SQL 2005 UNPIVOT comando o utilizzare una tecnica CROSS JOIN. Ecco alcuni esempi di entrambi. Nota che ho lasciato fuori mesi nel mezzo per mantenere le cose semplici. Basta aggiungerli.

-- CROSS JOIN method (also works in SQL 2000)
SELECT
   P.Project,
   Mo =
      DateAdd(mm,
         X.MonthNum,
         DateAdd(yy, P.[Year] - 1900, '19000101')
      ),
   Amount = 
      CASE X.MonthNum
         WHEN 0 THEN Jan
         WHEN 1 THEN Feb
         WHEN 11 THEN Dec
      END
FROM
   ProjectData P
   CROSS JOIN (
      SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 11
   ) X (MonthNum)

Ogni riga viene ripetuta 12 volte, quindi un'istruzione CASE estrae solo un mese per ogni riga, lasciando i dati piacevolmente non pivot.

-- UNPIVOT method
SELECT
    P.Project,
    Mo =
       DateAdd(mm,
          Convert(int, P.MonthNum),
          DateAdd(yy, P.[Year] - 1900, '19000101')
       ),
    P.Amount
FROM
   (
      SELECT Project, [Year], [0] = Jan, [1] = Feb, [11] = Dec
      FROM ProjectData
   ) X UNPIVOT (Amount FOR MonthNum IN ([0], [1], [11])) P

DROP TABLE ProjectData

Nessuno dei due metodi è sempre un chiaro vincitore delle prestazioni. A volte uno funziona meglio dell'altro (a seconda dei dati che vengono convertiti). Il metodo UNPIVOT utilizza un filtro nel piano di esecuzione che CROSS JOIN non utilizza.

Passaggio 2:ruota di nuovo

Ora, come utilizzare i dati non pivot. Non hai detto come sei qualcuno consumerà questo, ma poiché dovrai inserire i dati in un file di output di qualche tipo, propongo di utilizzare SSRS (Sql Server Reporting Services), fornito con SQL Server 2005 senza costi aggiuntivi.

Basta usare la Matrix oggetto report per trasformare una delle query precedenti. Questo oggetto determina felicemente i valori dei dati da inserire nelle etichette delle colonne in fase di esecuzione del report e suona esattamente come quello di cui hai bisogno. Se aggiungi una colonna che formatta la data esattamente come preferisci, puoi ordinare in base alla colonna Mo, ma utilizzare la nuova espressione come etichetta della colonna.

SSRS ha anche un'ampia varietà di formati e opzioni di pianificazione disponibili. Ad esempio, puoi inviare via email un file Excel o salvare una pagina Web in una condivisione file.

Per favore fatemi sapere se ho omesso qualcosa.

Per chiunque desideri vedere il codice sopra in azione, ecco alcuni script di creazione per te:

USE tempdb

CREATE TABLE ProjectData (
    Project varchar(10),
    [Year] int,
    Jan decimal(15, 2),
    Feb decimal(15, 2),
    Dec decimal(15, 2)
)

SET NOCOUNT ON

INSERT ProjectData VALUES ('11-11079', 2008, 0.0, 0.0, 75244.90)
INSERT ProjectData VALUES ('11-11079', 2009, 466.0, 0.0, 0.0)
INSERT ProjectData VALUES ('11-11079', 2010, 855.0, 0.0, 0.0)
INSERT ProjectData VALUES ('01-11052', 2009, 56131.0, 0.0, 0.0)