Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使用一个键组合数据库项以生成每个键一个项的表 我所拥有的_Sql - Fatal编程技术网

Sql 使用一个键组合数据库项以生成每个键一个项的表 我所拥有的

Sql 使用一个键组合数据库项以生成每个键一个项的表 我所拥有的,sql,Sql,我有一个sql数据库,其中有几个由整数键关联的表。下面是我的3个表、列名和每个表的一些示例数据。请记住,我只是想说明一下,它不是从数据库直接复制/粘贴的(因此,格式化是为了传达这一点,而不是sql数据库解析器可读的) 表1 ItemTable itemID,itemName, fruitOrVeggie, Color 1, Apple, Fruit, Red 2, Orange, Fruit, Orange 3, Carrot, Vegetable, Orange 表2 AttributeTy

我有一个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设置多个条目—这是我试图在新表中合并的部分

我想要什么 从这三个表中,我想创建一个像这样的新表

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, 
在这个新表中,itemID是一个唯一的键,因此每个itemID只有一个条目——这就是目标。请注意,每个attributeName现在是这个新表中的一列,ItemAttributeTable中的相应数据现在是如何在这里列出的,每个itemID都有一个条目(如果ItemAttributeTable没有该itemID的attributeID条目,则将字段留空)。我不想硬编码列名,因为我的实际数据大约有十几个列,我希望此查询具有足够的通用性,即使attributeName发生更改、添加或删除其中一些列,也能继续使用它

怎么去那里 我主要关注的是这类复杂查询所涉及的sql,尽管使用某种shell来实际创建这个新表可能很好。例如,一个查询,然后是一个运行该查询以创建ItemAttributeTable的Python脚本


关键部分是如何基于另一个表中的条目(在本例中为attributeName)在新表中创建列,然后如何从多个表中正确提取数据以填充此新表。

我将尝试以下方法:

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实现而有所不同。我建议在运行insert之前尝试Select部分,并查看返回的行是否与您希望新表中的行的外观相匹配。

在SQLServer2005+中,可以使用运算符旋转表值表达式。创建一个新表,并将查询产生的行插入其中

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
演示

如果要转换的列数(attributeName)未知,则可以使用动态透视

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 

的演示中,我希望能够从表中提取属性名称,而不必硬编码它们(就像您在这里所做的那样)。我会尝试一下,这至少是一个好的开始。没有这样的运气-我最终得到了所有Price、Weight和Diameter列的空值。从好的方面来说,“IT”中的内容可以正确地填充。第二行中的Price.attributeValue,Weight.attributeValue,Diameter.attributeValue应该如何工作,因为我认为这就是问题所在(尽管我可能错了)。您使用的是哪种DBMS?神谕博士后?这就是诀窍,谢谢你!我知道一定有办法做到这一点,而PIVOT似乎正是这一点。我还想感谢您的SQLFiddle示例和答案中的澄清/评论-感谢您的超越,非常感谢:)