2011-08-29 15 views
5

Mam grupę ludzi. Nazwijmy je A, B, C. Mam tabelę, która pokazuje, jak bardzo były one płatne co miesiąc ....Dane przestawne w T-SQL

PERSON|MONTH|PAID 
A  JAN 10 
A  FEB 20 
B  JAN 10 
B  FEB 20 
B  SEP 30 
C  JAN 10 
C  JUNE 20 
C  JULY 30 
C  SEP 40 

tej tabeli może i ma trwać przez wiele lat ..

Czy istnieje sposób, aby obracać się w tej tabeli (nic tak naprawdę nie musi być agregowane, co zwykle dzieje się w czatach) W tabeli, która wygląda następująco?

 JAN FEB MAR APR MAY JUN JUL AGU SEP 
A 10  20 
B 10  20  -  -  -  -  -  -  30 
C 10  -  -  -  -  20  30  -  40 

Nie wpadłem na coś takiego, ale zakładam, że jest to powszechny problem w przypadku jakichkolwiek pomysłów?

+0

Można jeszcze " agregacja "w dniu" MIESIĄC ". Chodzi o to, że w twoim zbiorze danych jest już zagregowana. Po prostu użyj czegoś takiego jak 'SUMA'. – Yuck

+0

możesz to zrobić dla ustalonej liczby kolumn, Jan..Feb ..., nie możesz tego zrobić dla zmiennej nr kolumn –

+0

... Nie ma sposobu, aby to zrobić dla zmiennych kolumn? – JBone

Odpowiedz

3

Jeśli używasz SQL Server 2005 (lub nowszy), oto kod:

DECLARE @cols VARCHAR(1000) 
DECLARE @sqlquery VARCHAR(2000) 

SELECT @cols = STUFF((SELECT distinct ',' + QuoteName([Month]) 
         FROM YourTable FOR XML PATH('')), 1, 1, '') 


SET @sqlquery = 'SELECT * FROM 
     (SELECT Person, Month, Paid 
     FROM YourTable) base 
     PIVOT (Sum(Paid) FOR [Person] 
     IN (' + @cols + ')) AS finalpivot' 

EXECUTE (@sqlquery) 

To będzie działać bez względu na to ile masz inny stan. Dynamicznie składa zapytanie z PIVOT. Jedynym sposobem na wykonanie PIVOT z dynamicznymi kolumnami jest dynamiczne składanie zapytania, które można wykonać w SQL Server.

Inne przykłady:

2

Nie jestem pewien, dlaczego trzeba dynamiczną # kolumn, ponieważ istnieje zawsze 12 miesięcy w roku. Również twoje nazwy miesięcy wydają się nieco niespójne pod względem długości.

Przykładowy wynik zestaw:

SELECT * FROM (SELECT 'A' [PERSON],'JAN' [MONTH],'10' [PAID] 
UNION SELECT 'A','FEB',20 
UNION SELECT 'B','JAN',10 
UNION SELECT 'B','FEB',20 
UNION SELECT 'B','SEP',30 
UNION SELECT 'C','JAN',10 
UNION SELECT 'C','JUNE',20 
UNION SELECT 'C','JULY',30 
UNION SELECT 'C','SEP',40) AS A 
PIVOT (SUM([PAID]) FOR [MONTH] IN ([JAN],[FEB],[MARCH],[APRIL],[MAY],[JUNE],[JULY],[AUG],[SEP],[OCT],[NOV],[DEC])) p 

Przeciwko stole ten stałby się:

SELECT [PERSON],[MONTH],[PAID] 
FROM [YOURTABLE] 
PIVOT (SUM([PAID]) FOR [MONTH] IN ([JAN],[FEB],[MARCH],[APRIL],[MAY],[JUNE],[JULY],[AUG],[SEP],[OCT],[NOV],[DEC])) p 

Jeśli dodać kolumnę roku wygląda tak:

SELECT * FROM (SELECT 'A' [PERSON],'JAN' [MONTH],'10' [PAID], 2011 [YEAR] 
UNION SELECT 'A','FEB',20, 2011 
UNION SELECT 'B','JAN',10, 2011 
UNION SELECT 'A','FEB',20, 2010 
UNION SELECT 'B','JAN',10, 2010 
UNION SELECT 'B','FEB',20,2011 
UNION SELECT 'B','SEP',30,2011 
UNION SELECT 'C','JAN',10,2011 
UNION SELECT 'C','JUNE',20,2011 
UNION SELECT 'C','JULY',30,2011 
UNION SELECT 'C','SEP',40,2011) AS A 
PIVOT (SUM([PAID]) FOR [MONTH] IN ([JAN],[FEB],[MARCH],[APRIL],[MAY],[JUNE],[JULY],[AUG],[SEP],[OCT],[NOV],[DEC])) p 
+0

Potrzebujesz dynamicznej kolumny, ponieważ nie chcemy zapisywać miesięcy w każdym roku w kółko – JBone

+0

Nie ma powodu, że musisz, jeśli [ROK] jest ustaloną kolumną. Zobacz mój trzeci przykład. – Kenneth