2013-11-27 50 views
1

我有一個表,看起來像這樣 -無法透過我的查詢透視表?

Id AttributeName AttributeValue 
A1 Atr1   A1V1 
A1 Atr2   A1V2 
A1 Atr3   A1V3 
A2 Atr1   A2V1 
A2 Atr2   A2V2 
A2 Atr3   A3V3 

在這個表中的每個ID具有完全相同的屬性,即ATR1,ATR2,ATR3。這些屬性的值是唯一的。

我想轉動此表並得到下面的輸出 -

Id Atr1 Atr2 Atr3 
A1 A1V1 A1V2 A1V3 
A2 A2V1 A2V2 A2V3 

我該怎麼辦呢?

我試過了一個查詢,並且出現錯誤 - Msg 156,Level 15,State 1,Line 21 關鍵字'FOR'附近的語法錯誤。

-- Create a temporary table 
DECLARE @MyTable TABLE 
(Id varchar(25), 
AttributeName varchar(30), 
AttributeValue varchar(30)) 
-- Load Sample Data 
INSERT INTO @MyTable VALUES ('A1', 'Atr1', 'A1V1') 
INSERT INTO @MyTable VALUES ('A1', 'Atr2', 'A1V2') 
INSERT INTO @MyTable VALUES ('A1', 'Atr3', 'A1V3') 
INSERT INTO @MyTable VALUES ('A2', 'Atr1', 'A2V1') 
INSERT INTO @MyTable VALUES ('A2', 'Atr2', 'A2V2') 
INSERT INTO @MyTable VALUES ('A2', 'Atr3', 'A3V3') 
SELECT Id, [Atr1], [Atr2],[Atr3] 
FROM 
( 
SELECT ID, AttributeName, AttributeValue 
FROM @MyTable) AS SourceTable 
PIVOT 
(
    AttributeValue 
    FOR AttributeName IN ([ATR1], [ATR2], [ATR3]) 
) AS pvt 
+0

這個例子是改編自 - http://archive.msdn.microsoft.com/SQLExamples/Wiki/View.aspx? title = PIVOTData&referTitle = UNPIVOTData –

+0

對於每個'id',是否有可能存在多個名爲'A1'的重複屬性名稱? – Taryn

+0

@bluefeet - 不太可能。但是,假設發生了,那麼我將如何對此進行查詢?謝謝。 –

回答

5

只是爲了在T擴大他的其他答案,PIVOT功能需要某種類型的聚合。由於要從一行轉換爲列的值是一個字符串,因此您僅限於使用max()min()聚合函數。

而當你有一個AttributeName/AttributeValue對,如果你必須爲每個ID多對@Muhammed Ali's答案將工作,那麼你將只返回無論是maxmin值。

例如,如果你的樣本數據是:

INSERT INTO @MyTable VALUES ('A1', 'Atr1', 'A1V1'); 
INSERT INTO @MyTable VALUES ('A1', 'Atr1', 'A1V4'); 
INSERT INTO @MyTable VALUES ('A1', 'Atr2', 'A1V2'); 
INSERT INTO @MyTable VALUES ('A1', 'Atr3', 'A1V3'); 
INSERT INTO @MyTable VALUES ('A2', 'Atr1', 'A2V1'); 
INSERT INTO @MyTable VALUES ('A2', 'Atr2', 'A2V2'); 
INSERT INTO @MyTable VALUES ('A2', 'Atr3', 'A3V3'); 

即使你有多行爲A1Atr1組合,其他查詢只返回max(attributevalue)

| ID | ATR1 | ATR2 | ATR3 | 
|----|------|------|------| 
| A1 | A1V4 | A1V2 | A1V3 | 
| A2 | A2V1 | A2V2 | A3V3 | 

我會猜測你實際上想要返回所有的組合。我建議擴展您的查詢以在查詢中包含窗口功能row_number()。此查詢會生成一個唯一值,然後將其包含在PIVOT的分組方面,並允許您爲每個ID返回多個行。

通過添加row_number(),查詢將類似於以下內容:

SELECT Id, [Atr1], [Atr2],[Atr3] 
FROM 
( 
    SELECT ID, AttributeName, AttributeValue, 
    row_number() over(partition by id, attributename 
         order by attributevalue) seq 
    FROM @MyTable 
) AS SourceTable 
PIVOT 
(
    max(AttributeValue) 
    FOR AttributeName IN ([ATR1], [ATR2], [ATR3]) 
) AS pvt 
order by id; 

SQL Fiddle with Demo。你會得到一個返回所有行的結果:

| ID | ATR1 | ATR2 | ATR3 | 
|----|------|--------|--------| 
| A1 | A1V1 | A1V2 | A1V3 | 
| A1 | A1V4 | (null) | (null) | 
| A2 | A2V1 | A2V2 | A3V3 | 

如果您有麻煩抓PIVOT的概念,那麼我建議看看使用一個CASE表達式的聚合函數的組合得到的結果。然後,您可以看到序列/ ID的分組:

SELECT Id, 
    max(case when attributename = 'Atr1' then attributevalue end) Atr1, 
    max(case when attributename = 'Atr2' then attributevalue end) Atr2, 
    max(case when attributename = 'Atr3' then attributevalue end) Atr3 
FROM 
( 
    SELECT ID, AttributeName, AttributeValue, 
    row_number() over(partition by id, attributename 
         order by attributevalue) seq 
    FROM @MyTable 
) AS SourceTable 
group by id, seq 

SQL Fiddle with Demo

+1

+1的解釋 –

+0

是的,藍色的腳,你的假設是正確的。我想要所有的對都被返回。順便說一下,MAX如何知道AttributeValue列中哪個AttributeValue爲最大值以及如何將其分配給正確的ID? –

+0

@ Trojan.ZBOT我不知道我理解你的問題,row_number是通過'attributevalue'排序數據,然後樞軸使用最大聚合的組合,但關鍵是它是通過' id'和由row_number創建的序列號 - 該分組獲取正確的行/列中的數據。 – Taryn

1
DECLARE @MyTable TABLE 
(Id varchar(25), 
AttributeName varchar(30), 
AttributeValue varchar(30)) 
-- Load Sample Data 
INSERT INTO @MyTable VALUES ('A1', 'Atr1', 'A1V1') 
INSERT INTO @MyTable VALUES ('A1', 'Atr2', 'A1V2') 
INSERT INTO @MyTable VALUES ('A1', 'Atr3', 'A1V3') 
INSERT INTO @MyTable VALUES ('A2', 'Atr1', 'A2V1') 
INSERT INTO @MyTable VALUES ('A2', 'Atr2', 'A2V2') 
INSERT INTO @MyTable VALUES ('A2', 'Atr3', 'A3V3') 
SELECT Id, [Atr1], [Atr2],[Atr3] 
FROM 
( 
SELECT ID, AttributeName, AttributeValue 
FROM @MyTable) AS SourceTable 
PIVOT 
(
    MAX(AttributeValue) 
    FOR AttributeName IN ([ATR1], [ATR2], [ATR3]) 
) AS pvt 

你缺少你的功能透視表語法

結果集

Id Atr1 Atr2 Atr3 
A1 A1V1 A1V2 A1V3 
A2 A2V1 A2V2 A3V3 
+0

謝謝穆罕默德。我不知道我必須在我的一列中使用函數。順便說一句,MAX功能在這種情況下如何提供幫助?它如何從AttributeValue列中選擇正確的值? –

+0

這是PIVOT語法,你必須有某種函數來讓數據透視表工作,因爲它是一個varchar列MAX函數工作得很好。在這裏閱讀更多詳細信息http://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx –

+0

再次感謝。如果它是非varchar列,會有什麼問題嗎? –

0

試試這個:

select id, 
     max(case AttributeName when 'Atr1' then AttributeName else '' end) as atr1, 
     max(case AttributeName when 'Atr2' then AttributeName else '' end) as atr2, 
     max(case AttributeName when 'Atr3' then AttributeName else '' end) as atr3, 
     AttributeValue 
    from YourTable 
group by id, AttributeValue 
order by id