2011-08-24 14 views
6

SELECT Name1, Name2, Value FROM mytable mang lại cho tôi những kết quả thiết lập sau đây:Máy chủ SQL PIVOT có lẽ?

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

Làm thế nào để dịch đó để:

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

Cảm ơn,

+1

Hi @user! Bạn đang sử dụng DBMS nào? – jadarnel27

+0

Có phải A và B là danh sách hằng số cố định không? – Neil

+0

@ jadarnel27 - Có gợi ý trong tiêu đề của câu hỏi;) – Tony

Trả lời

1

Bạn có thể sử dụng một điều khoản PIVOT. truy vấn của bạn có thể là một cái gì đó như thế này:

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 

sử dụng dữ liệu mẫu của bạn ở trên, kết quả của tôi là

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

EDIT:

Vì bạn có một số không rõ các cột, bạn sẽ cần phải xem xét sử dụng SQL động và có một số câu trả lời ở đây về SO về điều đó với PIVOT.

SQL Server 2005 Pivot on Unknown Number of Columns

Pivot Table and Concatenate Columns

+0

Vấn đề là OP không thể giới hạn đầu ra thành A, B. Cũng có thể có C, ..., X, như ông đã nêu trong một trong các nhận xét. –

+0

Tôi đã thực hiện một vài sửa đổi và có thể làm cho nó hoạt động bằng cách sử dụng ví dụ này và http://stackoverflow.com/questions/159456/pivot-table-and-concatenate-columns-sql-problem#159803. Một điều cuối cùng, làm thế nào tôi sẽ đi về việc thay thế các NULL với một String. Tôi đã thử một CASE nhưng nó chỉ thay thế trường 'Giá trị' có giá trị, không phải là NULLs – user683302

+0

Tôi đã cập nhật truy vấn PIVOT ở trên bằng cách sử dụng CASE và thay đổi giá trị NUll thành chuỗi. – Taryn

4

Tôi không có SQL Server chạy đây tại nơi làm việc vì vậy đây có thể không phải do hoàn toàn syntatically đúng nhưng một cách tiếp cận sẽ được cross lập bảng

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 

Đối với số biến các cột bạn có thể sử dụng SQL động:

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 ... trả lời SO câu hỏi tại nơi làm việc =) – jadarnel27

+0

Tôi đã chờ mã của tôi để biên dịch :-P – Zugwalt

+2

Có nhiều [xây dựng hơn] (http: // xkcd.com/303/) những điều bạn có thể làm trong khi mã của bạn đang biên dịch;) Tôi đã đăng nhận xét đó trong khi tôi đang làm việc cũng haha ​​ – jadarnel27

11

Vì bạn đang sử dụng SQL Server 2005, đây là mã:

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) 

này sẽ làm việc dù có bao nhiêu trạng thái khác nhau mà bạn có. Nó tự động lắp ráp một truy vấn với PIVOT. Cách duy nhất bạn có thể làm PIVOT với các cột động là bằng cách lắp ráp truy vấn động, có thể được thực hiện trong SQL Server.

ví dụ khác:

+2

+1 cho 'QuoteName' –

+0

@Martin Nó tránh các cuộc tấn công tiêm! –

+1

+1 Tôi chỉ không nói nên lời. –