2011-08-24 37 views
6

SELECT Name1, Name2, Value FROM mytable daje mi następujący zestaw wyników:Prawdopodobnie SQL Server PIVOT?

 
Name1 Name2 Value 
A  P1  1 
A  P2  1 
A  P3  2 
B  P1  3 
B  P2  1 
B  P4  1 

Jak mogę przetłumaczyć na:

 
     A  B 
P1  1  4 
P2  1  1 
P3  2  null 
P4  null 1 

Dzięki,

+1

Hi @user! Jakiego DBMS używasz? – jadarnel27

+0

Czy A i B to stała lista stałych? – Neil

+0

@ jadarnel27 - W tytule pytania pojawia się podpowiedź;) – Tony

Odpowiedz

1

Można użyć PIVOT klauzuli. Zapytanie może być coś takiego:

WITH Source as (
    SELECT Name1, Name2, [Value] 
    FROM mytable 
) 

SELECT Name2, CASE WHEN A IS NOT NULL THEN A ELSE 'your string' END As A 
, CASE WHEN B IS NOT NULL THEN B ELSE 'your string' END As B 
FROM (
     SELECT Name2, Name1, [Value] 
     FROM Source 
) s 
PIVOT 
(
    MAX([Value]) FOR Name1 IN (A, B) -- any other Name1 would go here 
) p 

przy użyciu przykładowych danych powyżej, moje wyniki były

P1 1   3 
P2 1   1 
P3 2   your string 
P4 your string 1 

EDIT:

Skoro masz nieznaną liczbę kolumn, trzeba będzie spójrz na użycie dynamicznego SQL i istnieje kilka odpowiedzi tutaj na SO o tym z PIVOT.

SQL Server 2005 Pivot on Unknown Number of Columns

Pivot Table and Concatenate Columns

+0

Problem polega na tym, że OP nie może ograniczać wyjścia do A, B. Może też być C, ..., X, jak stwierdził w jednym z komentarzy. –

+0

Wprowadziłem kilka modyfikacji i udało mi się uruchomić go za pomocą tego przykładu i http://stackoverflow.com/questions/159456/pivot-table-and-concatenate-columns-sql-problem#159803. Ostatnią rzeczą, jak chciałbym zastąpić NULL innym ciągiem. Próbowałem CASE, ale zastępuje tylko pola "Value", które mają wartości, a nie NULLs – user683302

+0

I zaktualizowane powyższe zapytanie PIVOT za pomocą CASE i zmienia wartości NUll na ciąg znaków. – Taryn

4

nie mam SQL Server działa tu w pracy, więc nie może się zupełnie syntatically poprawne, ale jedno podejście byłoby krzyż tabelaryczne

SELECT name2 
    , SUM(CASE WHEN name1 = 'A' THEN value END) AS A 
    , SUM(CASE WHEN name1 = 'B' THEN value END) AS B 
FROM table 
GROUP BY name2 

dla numeru zmiennej kolumn można użyć dynamicznego SQL:

DECLARE @sql varchar(max) 
SELECT @sql = COALESCE(@sql+',','') + 'SUM(CASE WHEN nane1 = '''+name1+''' THEN value END) AS ['+name1']' FROM table 

SET @sql = 'SELECT name2, '[email protected]+' FROM table GROUP BY name2' 

EXEC(@sql) 
+3

Tisk, tisk ... odpowiadając na pytania SO w pracy =) – jadarnel27

+0

Czekałem na mój kod do kompilacji :-P – Zugwalt

+2

Istnieje wiele [bardziej konstruktywne] (http: // xkcd.com/303/) rzeczy, które możesz zrobić podczas kompilacji kodu;) Wysłałem ten komentarz, gdy byłem w pracy, a także haha ​​ – jadarnel27

11

Ponieważ używasz SQL Server 2005, oto kod:

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

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


SET @sqlquery = 'SELECT * FROM 
     (SELECT Name2, Name1, Value 
     FROM myTable) base 
     PIVOT (Sum(Value) FOR [Name1] 
     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

+1 dla 'QuoteName' –

+0

@Martin To unika ataków iniekcyjnych! –

+1

+1 Jestem po prostu niemym. –