我有一个带有电子商务店面数据库的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
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?
答案 0 :(得分: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
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
有一种方法可以动态构建列(即颜色和大小列),可以看出here.确保数据库上的数据库兼容级别设置为大于2000的值,否则您将获得奇怪的错误。
答案 1 :(得分:0)
过去,我创建的物理表仅供阅读之用。您上面的结构对于存储而言非常好,但报告很糟糕。
所以你可以做以下事情: 编写一个脚本(每晚安排)或触发器(在数据更改时)执行以下任务:
首先,您将动态浏览每个产品并构建一个静态表“Product_ [ProductName]”
然后浏览每个产品的每个ProductAttributeTypes,并在相应的Product表上创建/更新/删除物理列。
然后,使用基于OrderItemsToProductAttributes和ProductAttributes的正确值填充该表
这只是一个粗略的想法。确保将OrderID存储在“静态”/“展平”表中。并确保你做了你需要做的一切。但在那之后,您应该能够从那些平坦的表中拉出来获取所需的数据。
答案 2 :(得分: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
然后我可以只与视图交互,但是,我在表上有一个触发器,必须添加任何新的动态属性,这会重新创建此视图,因此我可以假设视图始终是正确的。