2009-08-30 8 views
0

私はEコマースの店頭用データベースを持つ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コマンドを使用できます。 (動的に列を構築する方法があり

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 

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 

PIVOT後の最終的な結果は次のようになります。OrderAttributesセット以下の例ではhere.

は次のようになります参照してください。表示されるように、here.データベースのデータベース互換性レベルが2000より大きい値に設定されていることを確認するか、奇妙なエラーが発生します。

+0

どのように?集計関数を使用していないときは?私はIDなどを要約したくありません。 – MartinHN

+0

私はこれがとても近いと思っていますが、ColorカラムとSizeカラムの両方の値はnullです。たぶん小さなディテールが欠落しているのでしょうか? – MartinHN

+0

これは、OrderItemsToProductAttributesという表にProductAttributeTypeIdがあり、これをサンプルb/cに入れなかったことです。これは結合(第3の通常のフォームとすべて)を介して参照する必要があります。 SELECT AttrPivot.OrderItemId、 isnull([Size]、 'NA')AS [Size]、 isnull([Color]、 'NA)この例では、 ')ASカラー FROM OrderAttributes – JBrooks

0

これまでは、読み込み専用の物理テーブルを作成しました。あなたが上記の構造は記憶には大変ですが、報告にはひどいです。 、

まず、動的に各製品を通過し、建設すると、次のタスクを実行している スクリプトを書く(それが夜間に予定されている)、または(データ変更の)トリガー:

は、だからあなたは次のことを行うことができます静的テーブルProduct_ [ProductName]

各製品の各ProductAttributeTypesを調べ、対応するProductテーブルの物理列を作成/更新/削除します。

その後、適切なOrderItemsToProductAttributesに基づいた値とProductAttributes

これは単なる目安であると、そのテーブルを埋めます。 OrderIDを "Static"/"Flattened"テーブルに格納していることを確認してください。そして、あなたがする必要があるすべてのことを確実にしてください。しかしその後、必要なデータを得るために、それらの平らなテーブルから引き出すことができるはずです。

+0

あなたの意見がわかります。ストレージとレポートのデータベース設計には競合と限界があることに同意します。 しかし、このクエリは、冗長性、更新の遅延などの問題を引き起こすため、集計テーブルを使用するのに十分重いとは思いません。 – MartinHN

0

ピボットが最善の策ですが、私は報告目的のためにした、そしてそれは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 

その後、私はちょうど対話することができますこのビューを再作成する新しい動的属性を追加する必要があるため、ビューが常に正しいと見なすことができます。

関連する問題