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

SQL:ruota più colonne senza aggregazioni

Parte del problema è che hai denormalizzato i dati su più colonne che vuoi ruotare. Idealmente, dovresti considerare di correggere la struttura della tua tabella in modo che sia più facile da mantenere e interrogare. Se non sei in grado di correggere la struttura della tabella, devi prima annullare il pivot delle colonne per poi applicare PIVOT per ottenere il risultato finale.

Il processo UNPIVOT prenderà più colonne e le convertirà in più righe. A seconda della versione di SQL Server in uso, è possibile eseguire questa operazione in alcuni modi. È possibile utilizzare la funzione UNPIVOT o poiché si utilizza SQL Server 2008, è possibile utilizzare CROSS APPLY con la clausola VALUES per annullare il pivot.

Il codice CROSS APPLY/VALUES sarà:

select t.producttitle, c.col, c.value
from tmpData t
cross apply
(
  values (abvrMonthName, MonthAvg), (abvrMonthNameCount, MonthCount)
) c (col, value)

Vedi SQL Fiddle con demo . Questo prende le tue colonne multiple e inserisce i dati in un formato simile a questo:

| PRODUCTTITLE |  COL | VALUE |
-------------------------------
|    Product 1 |  Dec |     0 |
|    Product 1 | Dec# |     0 |
|    Product 1 |  Nov |     0 |
|    Product 1 | Nov# |     0 |
|    Product 1 |  Oct |     0 |
|    Product 1 | Oct# |     0 |
|    Product 1 |  Sep |     0 |
|    Product 1 | Sep# |     0 |

Una volta che i dati sono in questo formato, puoi applicare il PIVOT ai valori in col che contiene i nomi dei mesi:

select producttitle, jan, [jan#], feb, [feb#], mar, [mar#], apr, [apr#],
  may, [may#], jun, [jun#], jul, [jul#], aug, [aug#],
  sep, [sep#], oct, [oct#], nov, [nov#], dec, [dec#]
from
(
  select t.producttitle, c.col, c.value
  from tmpData t
  cross apply
  (
    values (abvrMonthName, MonthAvg), (abvrMonthNameCount, MonthCount)
  ) c (col, value)
) d
pivot
(
  sum(value)
  for col in (jan, [jan#], feb, [feb#], mar, [mar#], apr, [apr#],
              may, [may#], jun, [jun#], jul, [jul#], aug, [aug#],
              sep, [sep#], oct, [oct#], nov, [nov#], dec, [dec#])
) piv;

Vedi SQL Fiddle con demo . Questo dà un risultato:

| PRODUCTTITLE | JAN | JAN# |  FEB | FEB# |  MAR | MAR# |  APR | APR# |  MAY | MAY# | JUN | JUN# | JUL | JUL# | AUG | AUG# | SEP | SEP# | OCT | OCT# | NOV | NOV# | DEC | DEC# |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|    Product 1 |   5 |    2 |    5 |    1 |    5 |    4 |    5 |    6 | 4.44 |    9 |   5 |    1 |   0 |    0 |   0 |    0 |   0 |    0 |   0 |    0 |   0 |    0 |   0 |    0 |
|    Product 2 |   0 |    0 |    0 |    0 |    0 |    0 | 4.33 |    3 | 4.67 |    3 |   5 |    1 |   0 |    0 |   0 |    0 |   0 |    0 |   0 |    0 |   0 |    0 |   0 |    0 |
|    Product 3 | 4.6 |    5 | 4.75 |    8 | 4.75 |    8 |    4 |    6 |    5 |    6 |   5 |    3 |   0 |    0 |   0 |    0 |   0 |    0 |   0 |    0 |   0 |    0 |   0 |    0 |