2012-02-14 34 views
0
-- Pivot table with one row and four columns 

SELECT 'Values' tValues, 
    ID,Name,ValueID,Value FROM (

     Select ID,Name,ValueID,Value FROM Table WHERE OptionID = 1000000 

    ) AS SourceTable 

    PIVOT ( 

     COUNT(tValues) 
     FOR tValues IN (ID,Attribute,ValueID,Value) 

    ) AS PivotTable; 

我要去關的例子在Microsoft.com:http://msdn.microsoft.com/en-us/library/ms177410.aspx有一排四列透視表

但也有繞樞軸我真的不明白一些事情,所以不要當你在上面的代碼中看到它時會感到驚訝,例如COUNT(tValues),我不知道這是爲什麼,通過從微軟的例子來看,它似乎總是某種數值,所以我想我會嘗試它看它是否會返回一些東西,但它返回的是一個錯誤。總之,如果有人在那裏可以分享爲什麼這個查詢不起作用,並且可能解釋什麼FOR以上的數字值用於?

Table containts行的x量,四列,所以它看起來是這樣的:

ID | Name | ValueID | Value 

100 | Color | 10000 | Black 
101 | Size | 10005 | Large 

輸出應該是這樣的:

Name_100 | Color | Name_101 | Size | 

10000  | Black | 10005  | Large | 
+0

你可以顯示你的表格,樣本數據和所需的結果嗎?你能否解釋一下「不起作用」的含義? – 2012-02-14 03:17:45

+0

@Aaron:'Table'是一列X列行數爲4列的結果,整個查詢不起作用。甚至可以樞軸處理這個? – 2012-02-14 03:20:05

+1

我不知道。這就是爲什麼我要求瞭解你想要完成的更多細節。你可以顯示你的表結構('CREATE TABLE'),樣本數據以及你想要的查詢輸出結果嗎?否則,我不知道這個數據透視預計會處理什麼「這個」。 – 2012-02-14 03:22:04

回答

1

也許是這樣的。

這隻有在名稱列是唯一的時才起作用。如果沒有,那麼你可能想追加一個ID。

所以首先一些測試數據:

CREATE TABLE tblValues 
    (
     ID INT, 
     Name VARCHAR(100), 
     ValueID INT, 
     Value VARCHAR(100) 
    ) 

INSERT INTO tblValues 
VALUES 
    (100,'Color',10000,'Black'), 
    (101,'Size',10005,'Large') 

然後,你需要得到列轉動上:

DECLARE @cols VARCHAR(MAX) 
;WITH CTE AS 
(
    SELECT 
     'Name_'+CAST(tbl.ID AS VARCHAR(100)) AS Name, 
     'Name_'+CAST(tbl.ID AS VARCHAR(100)) AS Sort, 
     tbl.ID 
    FROM 
     tblValues AS tbl 
    UNION ALL 
    SELECT 
     tbl.Name, 
     'Value_'+CAST(tbl.ID AS VARCHAR(100)) AS Sort, 
     tbl.ID 
    FROM 
     tblValues AS tbl 
) 
SELECT 
    @cols = COALESCE(@cols + ','+QUOTENAME(Name), 
       QUOTENAME(Name)) 
FROM 
    CTE 
ORDER BY 
    CTE.ID, 
    CTE.Sort 

然後宣佈和執行動態SQL這樣的:

DECLARE @query NVARCHAR(4000)= 
N'SELECT 
    * 
FROM 
(
    SELECT 
     ''Name_''+CAST(tbl.ID AS VARCHAR(100)) AS pivotName, 
     CAST(tbl.ValueID AS VARCHAR(100)) AS name 
    FROM 
     tblValues AS tbl 
    UNION ALL 
    SELECT 
     tbl.Name AS pivotName, 
     tbl.Value AS name 
    FROM 
     tblValues AS tbl 
) AS p 
PIVOT 
(
    MAX(name) 
    FOR pivotName IN ('[email protected]+') 
) AS pvt' 

EXECUTE(@query) 

然後在我的情況下,我會刪除我創建的表

DROP TABLE tblValues 

編輯

或者在你情況下,應該是這樣的:

第一列:

DECLARE @cols VARCHAR(MAX) 
;WITH CTE AS 
(
    SELECT 
     'Name_'+CAST(tbl.ID AS VARCHAR(100)) AS Name, 
     'Name_'+CAST(tbl.ID AS VARCHAR(100)) AS Sort, 
     tbl.ID 
    FROM 
     [Table] AS tbl 
    WHERE 
     tbl.OptionID = 1000000 
    UNION ALL 
    SELECT 
     tbl.Name, 
     'Value_'+CAST(tbl.ID AS VARCHAR(100)) AS Sort, 
     tbl.ID 
    FROM 
     [Table] AS tbl 
    WHERE 
     tbl.OptionID = 1000000 
) 
SELECT 
    @cols = COALESCE(@cols + ','+QUOTENAME(Name), 
       QUOTENAME(Name)) 
FROM 
    CTE 
ORDER BY 
    CTE.ID, 
    CTE.Sort 

然後動態SQL。

DECLARE @query NVARCHAR(4000)= 
N'SELECT 
    * 
FROM 
(
    SELECT 
     ''Name_''+CAST(tbl.ID AS VARCHAR(100)) AS pivotName, 
     CAST(tbl.ValueID AS VARCHAR(100)) AS name 
    FROM 
     [Table] AS tbl 
    WHERE 
     tbl.OptionID = 1000000 
    UNION ALL 
    SELECT 
     tbl.Name AS pivotName, 
     tbl.Value AS name 
    FROM 
     [Table] AS tbl 
    WHERE 
     tbl.OptionID = 1000000 
) AS p 
PIVOT 
(
    MAX(name) 
    FOR pivotName IN ('[email protected]+') 
) AS pvt' 

EXECUTE(@query) 

您不需要創建表或刪除表。那只是因爲我的數據庫中沒有你的表格,並且如果有人想要運行這個例子。

+0

感謝您的迴應,當原始表已經具有這些值時,是否需要創建表'tblValues'? (如問題中的'SELECT'語句所示?) – 2012-02-14 14:39:26

+0

我更新了答案。如果你想得到答案,你可以考慮接受它。 – Arion 2012-02-14 15:07:43

1

如果你想使用透視有不同數量的列的表,那麼我會建議使用沿着行的東西;

DECLARE @cols VARCHAR(4000) 
    DECLARE @query VARCHAR(8000) 
    SELECT @cols = STUFF((SELECT DISTINCT 
      '],[' + Name 
         FROM Table 
         ORDER BY '],[' + Name 
         FOR XML PATH('') 
        ), 1, 2, '') + ']' 

    SET @query = 
    'SELECT * FROM 
    (
     SELECT col1, col2, col3, whateverColYourInterestedIn, Name, Value 
     FROM Table 
    )t 
    PIVOT (MAX(Value) FOR Name 
    IN ('[email protected]+')) AS pvt' 

    EXECUTE (@query) 

這可能不太正確,但它應該有希望成爲你的起點。

欲瞭解更多信息,檢查鏈接,如thisthis

+0

這是我會建議的,但是您的查詢需要一些清理。您在SELECT DISTINCT中缺少單引號,並且在子查詢中執行ORDER BY是否定的 - SQL Server實際上應該對此抱怨。 :) – FarligOpptreden 2012-02-14 08:12:06

+0

感謝您的注意。我已添加缺少的報價。子查詢中沒有ORDER BY,它用於傳遞給STUFF的參數。這是我所看到的用於構建動態列列表的所有示例,並且我自己也成功地使用了它。我同意代碼可能不起作用,但希望它能給OP一些想法,相關鏈接將幫助他們將其餘部分放在一起並使其查詢工作。 – 2012-02-14 08:24:55

+0

我實際上是指查詢中傳遞給STUFF的ORDER BY。我有幾次SQL Server的呻吟,我可以獲得的最佳解決方案是將SELECT放入一個帶有ROW_NUMBER()OVER(ORDER BY ...)的CTE中以獲取數據,然後選擇STUFF中的CTE相關欄目。希望這是有道理的...... P我贊成你的答案,因爲我相信這是最有活力的實現。您可以嘗試調用sp_ExecuteSQL以確保查詢路徑也被緩存...... – FarligOpptreden 2012-02-14 08:41:58