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

Dynamiske kolonner - SQL Server - Måneder som kolonner

Dine data er allerede pivoteret, men skal pivoteres på et andet niveau. Jeg tror, ​​at den bedste måde at håndtere dette på er at fjerne pivot først og derefter håndtere det korrekte pivotniveau.

Trin 1:Fjern pivot

Du kan bruge SQL 2005 UNPIVOT kommando, eller brug en CROSS JOIN-teknik. Her er eksempler på begge dele. Bemærk, at jeg udelod måneder i midten for at holde tingene enkle. Bare tilføje dem.

-- 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)

Hver række gentages 12 gange, derefter trækker en CASE-erklæring kun én måned ud for hver række, hvilket efterlader dataene pænt upivoteret.

-- 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

Ingen af ​​metoderne er en klar præstationsvinder hele tiden. Nogle gange fungerer den ene bedre end den anden (afhængigt af de data, der pivoteres). UNPIVOT-metoden bruger et filter i udførelsesplanen, som CROSS JOIN ikke gør.

Trin 2:Pivot igen

Nu, hvordan man bruger de ikke-pivoterede data. Du sagde ikke, hvordan du nogen vil forbruge dette, men da du bliver nødt til at lægge dataene i en outputfil af en eller anden art, foreslår jeg at bruge SSRS (Sql Server Reporting Services), som leveres med SQL Server 2005 uden ekstra omkostninger.

Brug bare matrix rapporter objekt for at pivotere en af ​​forespørgslerne ovenfor. Dette objekt bestemmer gladeligt de dataværdier, der skal laves til kolonneetiketter ved rapportkørsel, og det lyder som præcis det, du har brug for. Hvis du tilføjer en kolonne, der formaterer datoen præcis, som du vil, kan du sortere efter Mo-kolonnen, men bruge det nye udtryk som kolonneetiket.

SSRS har også en bred vifte af formater og planlægningsmuligheder. For eksempel kan du få den til at sende en Excel-fil til e-mail eller gemme en webside til en fildeling.

Fortæl mig venligst, hvis jeg har udeladt noget.

For alle, der gerne vil se koden ovenfor i aktion, er her et script til dig:

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)


  1. syntaksfejl:'afgrænser' er ikke gyldigt input her

  2. ORA-00903:ugyldigt tabelnavn på PreparedStatement

  3. Udfør flere SQL-sætninger i java

  4. database-e-mail med vedhæftet fil (excel-fil / pdf-fil)?