2009-08-30 29 views
0

我有一個MS SQL Server與電子商務店面的數據庫。SQL使行成列,PIVOT也許

這是一些我的表:

Products: 
Id | Name | Price 

ProductAttributeTypes: -Color, Size, Format 
Id | Name 

ProductAttributes: --Red, Green, 12x20 cm, Mirrored 
Id | ProductAttributeTypeId | Name 

Orders: 
Id | DateCreated 

OrderItems: 
Id | OrderId | ProductId 

OrderItemsToProductAttributes: --Relates an OrderItem to its product and selected attributes 
OrderItemId | ProductAttributeId | ProductAttributeTypeId | ProductId 

我想從表中的OrderItems選擇,看看哪個項目已被購買。

要查看選擇哪種變體(ProductAtriibutes),我希望那些結果集中的「動態」列。

所以結果集應該是這樣的:

OrderItemId | ProductId | ProductName | Color | Size | Format 
     1234   123 Mount. Bike Red  2x20 Mirror 

我不知道,如果PIVOT是用的東西?我沒有使用任何聚合函數,所以我猜不...

是否有任何SQL Ninjas可以幫助我?

回答

1

如果您使用的是sql2005或2008,則可以使用pivot命令。見here.

在組將類似於OrderAttributes下面的例子:

OrderItemId AttName AttValue 
     ----- ------ ----- 
     100 Color Red 
     100 Size Small 
     101 Color Blue 
     101 Size Small 
     102 Color Red 
     102 Size Small 
     103 Color Blue 
     103 Size Large 

樞軸後的最終結果將是:

OrderItemId Size Color 
    ----- ------ ----- 
    100 Small Red 
    101 Small Blue 
    102 Small Red 
    103 Large Blue 

WITH OrderAttributes(OrderItemId, AttName, AttValue) 
    AS (
     SELECT 
     OrderItemId, 
     pat.Name AS AttName, 
     pa.Name AS AttValue 
     FROM OrderItemsToProductAttributes x 
     INNER JOIN ProductAttributes pa 
     ON x.ProductAttributeId = pa.id 
     INNER JOIN ProductAttributeTypes pat 
     ON pa.ProductAttributeTypeId = pat.Id 
    ) 

SELECT AttrPivot.OrderItemId, 
[Size] AS [Size], 
[Color] AS Color 
FROM OrderAttributes 
PIVOT ( 
     MAX([AttValue]) 
     FOR [AttName] IN ([Color],[Size]) 
    ) AS AttrPivot 
ORDER BY AttrPivot.OrderItemId 

有動態生成的列的方式(即顏色和大小列),因爲可以看到here.請確保您的數據庫的數據庫兼容級別設置爲大於2000的值,否則會出現奇怪的錯誤。

+0

如何?當我沒有使用任何聚合函數?我不想總結Ids或類似的東西。 – MartinHN 2009-08-30 23:11:23

+0

我認爲這一個現在非常接近 - 但Color和Size列的值都是null。也許只是一個小細節丟失? – MartinHN 2009-08-31 10:45:44

+0

有一件事可能會導致diff,你在表OrderItemsToProductAttributes中有ProductAttributeTypeId,我沒有把它放在我的樣本b/c中,這應該通過連接(第三範式和所有)來引用。如果你說它們可能有空值,那麼應該將其改爲如下形式: SELECTn AttrPivot.OrderItemId, isnull([Size],'NA')AS [Size], isnull([Color],'NA ')AS顏色 從OrderAttributes – JBrooks 2009-08-31 14:20:47

0

過去,我只爲了閱讀目的而創建了物理表。上面的結構非常適合存儲,但報告可怕。

所以,你可以做到以下幾點: 寫一個腳本(即夜間計劃)或觸發(數據更改)將執行以下任務:

首先,你要動態地去通過每一個產品和建立靜態表「Product_ [ProductName]」

然後檢查每個產品的每個ProductAttributeTypes,並在相應的Product表上創建/更新/刪除物理列。

然後,填寫基於OrderItemsToProductAttributes正確的價值觀和ProductAttributes

這只是一個粗略的想法,表。確保您將OrderID存儲在「Static」/「Flattened」表中。並確保你做你需要做的一切。但在此之後,您應該能夠從這些拼合的表格中拉出來獲取所需的數據。

+0

我明白你的觀點。我同意存儲與報告的數據庫設計有其衝突和限制。 但我不認爲這個查詢是足夠大的使用聚合表,因爲它給了我其他問題,如冗餘,延遲更新等。 – MartinHN 2009-08-30 23:08:44

0

Pivot是你最好的選擇,但我就是這樣做的報告的目的,並使其與SSIS很好地工作是創建一個視圖,然後有此查詢:

SELECT  [InputSetID], [InputSetName], CAST([470] AS int) AS [Created By], CAST([480] AS datetime) AS [Created], CAST([479] AS int) AS [Updated By], CAST([460] AS datetime) 
         AS [Updated] 
FROM   (SELECT  st.InputSetID, st.InputSetName, avt.InputSetID AS avtID, avt.AttributeID, avt.Value 
         FROM   app.InputSetAttributeValue avt JOIN 
               app.InputSets st ON avt.InputSetID = st.InputSetID) AS p PIVOT (MAX(Value) FOR AttributeID IN ([470], [480], [479], [460])) AS pvt 

然後我就可以相互作用與視圖,但是,我有一個表上的觸發器,必須添加任何新的動態屬性,重新創建此視圖,所以我可以假設視圖總是正確的。