Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

SQL — przestaw wiele kolumn bez agregatów

Częścią problemu jest to, że masz zdenormalizowane dane w wielu kolumnach, które chcesz przestawić. Najlepiej byłoby rozważyć poprawienie struktury tabeli, aby łatwiej było ją konserwować i wykonywać zapytania. Jeśli nie możesz naprawić struktury tabeli, powinieneś najpierw odwrócić kolumny, a następnie zastosować PIVOT, aby uzyskać ostateczny wynik.

Proces UNPIVOT zajmie wiele kolumn i przekształci je w wiele wierszy. W zależności od wersji programu SQL Server można to zrobić na kilka sposobów. Możesz użyć funkcji UNPIVOT lub ponieważ używasz SQL Server 2008, możesz użyć CROSS APPLY z klauzulą ​​VALUES, aby unpivot.

Kod CROSS APPLY/VALUES to:

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

Zobacz Skrzypce SQL z wersją demonstracyjną . Pobiera to wiele kolumn i umieszcza dane w formacie podobnym do tego:

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

Gdy dane będą już w tym formacie, możesz zastosować PIVOT do wartości w col który zawiera nazwy miesięcy:

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;

Zobacz SQL Fiddle z wersją demonstracyjną . Daje to wynik:

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server 2005 ROW_NUMBER() bez ORDER BY

  2. Jak zoptymalizować SQL 'XQuery'

  3. Zwróć listę schematów partycji w SQL Server (T-SQL)

  4. Jak naprawić „Wyrażenie ALTER TABLE SWITCH nie powiodło się” Msg 4982 (SQL Server)

  5. Jak sparametryzować ciąg połączenia z bazą danych w pakiecie SSIS?