Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Динамични колони - SQL Server - Месеци като колони

Вашите данни вече са насочени, но трябва да се насочат на различно ниво. Мисля, че най-добрият начин да се справите с това е първо да го отмените, а след това второ да обработите правилното ниво на завъртане.

Стъпка 1:Отмяна на завъртането

Можете да използвате SQL 2005 UNPIVOT или използвайте техника CROSS JOIN. Ето примери и за двете. Забележете, че оставих месеци по средата, за да опростя нещата. Просто ги добавете.

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

Всеки ред се повтаря 12 пъти, след което командата CASE изважда само един месец за всеки ред, оставяйки данните добре незавъртени.

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

Нито един от методите не е ясен победител в ефективността през цялото време. Понякога едното работи по-добре от другото (в зависимост от данните, които се обръщат). Методът UNPIVOT използва филтър в плана за изпълнение, който CROSS JOIN не използва.

Стъпка 2:Завъртете отново

Сега, как да използвате непивотирани данни. Не казахте как вашият някой ще изразходва това, но тъй като ще трябва да поставите данните в изходен файл от някакъв вид, предлагам да използвате SSRS (Sql Server Reporting Services), който идва с SQL Server 2005 без допълнително заплащане.

Просто използвайте Матрицата отчетен обект, за да завъртите една от горните заявки. Този обект с радост определя стойностите на данните, които да превърне в етикети на колони по време на изпълнение на отчета, и звучи като точно това, от което се нуждаете. Ако добавите колона, която форматира датата точно както искате, тогава можете да подредите по колоната Mo, но да използвате новия израз като етикет на колоната.

SSRS също има голямо разнообразие от налични формати и опции за планиране. Например, можете да го накарате да изпрати файл на Excel по имейл или да запише уеб страница в споделяне на файлове.

Моля, уведомете ме, ако съм пропуснал нещо.

За всеки, който би искал да види кода по-горе в действие, ето някакъв скрипт за създаване за вас:

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. T-SQL MERGE - откриване какво действие е предприело

  2. Получаване на максимална стойност от редове и присъединяване към друга таблица

  3. Как да промените колона, без да изпускате таблица в SQL 2008

  4. Как да приложа 3 стойности за 1 ред към 3 реда с всяка стойност?

  5. Съпоставяне на символи/търсене и заместване на знак по знак в SQL Server 2008 R2