1

私が持っているもの

整数キーで相互に関連するいくつかのテーブルを持つSQLデータベースがあります。これが私の3つのテーブル、列名、および各テーブルのサンプルデータです。アイデアを出すためにこれを入力しているだけであり、データベースからの直接のコピー/貼り付けではないことに注意してください(したがって、フォーマットは要点を伝えるためのものであり、SQLデータベースパーサーで読み取ることはできません)。

表1

ItemTable
itemID,itemName, fruitOrVeggie, Color
1, Apple, Fruit, Red
2, Orange, Fruit, Orange
3, Carrot, Vegetable, Orange

表2

AttributeTypesTable
attributeID,attributeName
1, Price
2, Weight
3, Diameter

表3

ItemAttributesTable
itemID,attributeID,attributeValue
1, 1, .75
1, 2, .5
1, 3, .7
2, 1, .9
2, 3, .7
3, 1, .3
3, 2, .5

ItemAttributesTableのitemIDごとに複数のエントリがあることに注意してください。これは、新しいテーブルに統合しようとしている部分です。

私が欲しいもの

これらの3つのテーブルから、このような新しいテーブルを作成します。

NewTable
itemID,itemName,fruitOrVeggie,Color,Price,Weight,Diameter
1, Apple, Fruit, Red, .75, .5, .7
2, Orange, Fruit, Orange, .9, , .7
3, Carrot, Vegetable, Orange, .3, .5, 

このNewTableでは、itemIDは一意のキーであるため、itemIDごとにエントリは1つだけです。これが目標です。各attributeNameがこの新しいテーブルの列になり、ItemAttributesTableの対応するデータが各itemIDの単一のエントリとともにここに一覧表示されることに注意してください(ItemAttributesTableにそのitemIDのそのattributeIDのエントリがない場合は、フィールドを空白のままにします) 。実際のデータには約12の列があるため、列名をハードコーディングする必要はありません。このクエリは、attributeNameが変更されても使用し続けることができるように十分に汎用性があり、一部を追加または削除します。それらなど。

そこに着く方法

私は主にこの種の複雑なクエリに関連するSQLを調べていますが、この新しいテーブルを実際に作成するためのある種のシェルがあればよいかもしれません。たとえば、クエリと、そのクエリを実行してItemAttributesTableを作成するPythonスクリプト。

重要な部分は、別のテーブル(この場合はattributeName)のエントリに基づいて新しいテーブルに列を作成する方法と、複数のテーブルからデータを適切にプルしてこの新しいテーブルにデータを入力する方法です。

4

2 に答える 2

2

SQLServer2005 +では、ピボット演算子を使用してテーブル値の式をローテーションできます。SELECT…INTOは新しいテーブルを作成し、クエリの結果の行をそのテーブルに挿入します

IF OBJECT_ID('NewTable') IS NOT NULL DROP TABLE NewTable
SELECT ItemID, ItemName, FruitOrVeggie, Color, Price, Weight, Diameter
INTO NewTable
FROM      
(      
 SELECT t.ItemID, t.ItemName, t.FruitOrVeggie, Color, attributeName, attributeValue
 FROM ItemTable t JOIN ItemAttributesTable at ON t.ItemID = at.ItemID
                  JOIN AttributeTypesTable tt ON at.attributeID = tt.attributeID
) x
PIVOT
(
 MAX(attributeValue) FOR attributeName IN ([Price], [Weight], [Diameter])
 ) p

SELECT *
FROM NewTable

SQLFiddleのデモ

また

変換する列(attributeName)の数が不明な場合は、動的PIVOTを使用できます。

DECLARE @cols AS nvarchar(max),
        @query AS nvarchar(max)

SELECT @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(attributeName)
                      FROM AttributeTypesTable
                      FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '')

IF OBJECT_ID('NewTable') IS NOT NULL DROP TABLE NewTable                      
SET @query = 'SELECT ItemID, ItemName, FruitOrVeggie, Color, ' + @cols + 
             'INTO NewTable FROM 
             (
              SELECT t.ItemID, t.ItemName, t.FruitOrVeggie, Color, attributeName, attributeValue
              FROM ItemTable t JOIN ItemAttributesTable at ON t.ItemID = at.ItemID
                               JOIN AttributeTypesTable tt ON at.attributeID = tt.attributeID
              ) x
              PIVOT
              (
               MAX(attributeValue) FOR attributeName IN (' + @cols + ')
               ) p '

EXEC(@query)

SELECT *
FROM NewTable 

SQLFiddleのデモ

于 2013-02-09T09:50:31.030 に答える
0

私はこのようなことを試みます:

INSERT INTO NEW TABLE (itemID, itemName, fruitOrVeggie, Color, Price, Weight, Diameter)
SELECT IT.itemID, IT.itemName, IT.fruitOrVeggie, IT.Color, Price.attributeValue, Weight.attributeValue, Diameter.attributeValue
FROM ItemTable IT
LEFT OUTER JOIN ( SELECT itemId, attributeValue
        FROM ItemAttributesTable
        WHERE attributeID = 1
    ) AS Price
ON Price.itemID = IT.itemID
LEFT OUTER JOIN ( SELECT itemId, attributeValue
        FROM ItemAttributesTable
        WHERE attributeID = 2
    ) AS Weight
ON Weight.itemID = IT.itemID
LEFT OUTER JOIN ( SELECT itemId, attributeValue
        FROM ItemAttributesTable
        WHERE attributeID = 3
    ) AS Diameter
ON Diameter.itemID = IT.itemID

挿入構文は、使用している特定のSQL実装によって異なります。挿入を実行する前に、選択部分を試して、返される行がnewTableの行の外観と一致するかどうかを確認することをお勧めします。

于 2013-02-09T03:45:32.907 に答える