Sql server SQL将行转换为列,可能是PIVOT
我有一个MS SQL Server和一个用于电子商务店面的数据库 这是我的一些表格:Sql server SQL将行转换为列,可能是PIVOT,sql-server,Sql Server,我有一个MS SQL Server和一个用于电子商务店面的数据库 这是我的一些表格: Products: Id | Name | Price ProductAttributeTypes: -Color, Size, Format Id | Name ProductAttributes: --Red, Green, 12x20 cm, Mirrored Id | ProductAttributeTypeId | Name Orders: Id | DateCreated O
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表中进行选择,以查看购买了哪些项目
要查看选择了哪种变体(ProductAttribute),我希望在resultset中将它们作为“动态”列
因此,结果集应该如下所示:
OrderItemId | ProductId | ProductName | Color | Size | Format
1234 123 Mount. Bike Red 2x20 Mirror
我不知道PIVOT是否适合使用?我没有使用任何聚合函数,所以我想没有
有什么SQL忍者可以帮我吗?过去,我创建物理表只是为了读取。上面的结构非常适合存储,但不适合报告 因此,您可以执行以下操作: 编写执行以下任务的脚本(每晚安排)或触发器(数据更改时): 首先,您将动态浏览每个产品,并构建一个静态表“Product[ProductName]” 然后检查每个产品的每个ProductAttributeType,并在相应的产品表上创建/更新/删除一个物理列 然后,根据OrderItemStopProductAttributes和ProductAttributes使用适当的值填充该表
这只是一个粗略的想法。确保在“静态”/“展平”表中存储OrderID。确保你做了所有你需要做的事情。但是在这之后,您应该能够开始从这些展开的表中提取所需的数据。如果您使用的是sql2005或2008,则可以使用pivot命令。看 在下面的示例中,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
有一种方法可以动态构建列(即颜色和大小列),如图所示,请确保数据库上的数据库兼容性级别设置为大于2000,否则会出现奇怪的错误。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
然后我就可以与视图交互,但是,我在表上有一个触发器,任何新的动态属性都必须添加到该触发器中,这会重新创建此视图,因此我可以假设视图总是正确的。我明白你的意思。我同意针对存储和报告的数据库设计有其冲突和局限性。但我认为这个查询不够重,无法使用聚合表,因为它会给我带来其他问题,如冗余、更新延迟等。如何解决?当我不使用任何聚合函数时?我不想对ID或诸如此类的内容进行汇总。我认为这一项现在非常接近——但是颜色和大小列的值都是空的。可能只是缺少一个小细节?有一件事可能会导致差异,您在OrderItemStopProductAttributes表中有ProductAttributeTypeId,我没有将其放在我的示例b/c中,这应该通过连接引用(第三个正常形式和全部)。如果您说它们可能有空值,那么应该将某些内容更改为:选择AttrPivot.OrderItemId,将isnull([Size],'NA')作为[Size],将isnull([Color],'NA')作为OrderAttributes中的颜色它没有空值。但我不知道为什么它返回null。如果在WITH语句中运行查询,则返回所有正确的数据-没有空值。但是,运行整个查询时,大小和颜色列的值都为空,我成功了。原因是每个属性的名称不存储为颜色、大小等。它存储为一个XML字符串,带有许多特定于区域性的值,以适应国际化。