想象一个带有属性的表(键值)和带有很多的父表。
LotId SomeText
----------- --------
1 Hello
2 World
AttributeId LotId Val Kind
----------- ----------- -------- --------
1 1 Foo1 Kind1
2 1 Foo2 Kind2
3 2 Bar1 Kind1
4 2 Bar2 Kind2
5 2 Bar3 Kind3
我正在使用UNPIVOT
-PIVOT
操作以以下形式获取数据:
LotId SomeText AttributeId LotId Kind1Val Kind AttributeId LotId Kind2Val Kind AttributeId LotId Kind3Val Kind
----------- -------- ----------- ----------- -------- -------- ----------- ----------- -------- -------- ----------- ----------- -------- --------
1 Hello 1 1 Foo1 Kind1 2 1 Foo2 Kind2 NULL NULL NULL NULL
2 World 3 2 Bar1 Kind1 4 2 Bar2 Kind2 5 2 Bar3 Kind3
如何选择远离属性表值的数据独立性。
错误结果的示例:
LotId SomeText attributeid_1 LotId_1 Value_1 Kind_1 attributeid_2 LotId_2 Value_2 Kind_2 attributeid_3 LotId_3 Value_3 Kind_3
----------- -------- ------------- -------- -------- -------- ------------- -------- -------- -------- ------------- -------- -------- --------
1 Hello 4 1 Foo1 Kind1 NULL NULL NULL NULL NULL NULL NULL NULL
2 World 1 2 Bar2 Kind2 3 2 Bar3 Kind3 2 2 Bar1 Kind8
为什么?
由于column 和in 中的Kind2
文本。Kind_1
Kind3
Kind_2
声明 @Lot 表 ( LotId INT 主键标识, SomeText VARCHAR(8)) 插入@Lot 值('你好'),('世界') 声明@属性表( AttributeId INT 主键标识, LotId INT, 瓦尔 VARCHAR(8), 类型 VARCHAR(8)) 插入@Attribute 值 (2, 'Bar2', 'Kind2'), (2, 'Bar1', 'Kind8'), (2, 'Bar3', 'Kind3'), (1,'Foo1','Kind1') 选择 * 从 ( 选择 LotId, 一些文本, col+'_'+CAST(rn as varchar(10)) col, 价值 从 ( 选择 l.LotId, l.SomeText, cast(a.AttributeId as varchar(8)) 属性id, cast(a.LotId as varchar(8)) a_LotId, a.Val, 一种, ROW_NUMBER() over(l.lotid order by a.kind 分区) rn 来自@Lot l 左加入@Attribute a 在 l.LotId = a.LotId ) 源代码 交叉申请 ( values ('attributeid', attributeid),('LotId', a_LotId), ('Value', Val), ('Kind', Kind) ) c (col, 值) ) d 枢 ( 最大值(值) 对于 col in (attributeid_1, LotId_1, Value_1, Kind_1, attribute_2、LotId_2、Value_2、Kind_2、 属性id_3、LotId_3、Value_3、Kind_3) ) piv
正确结果的示例:
LotId SomeText attributeid_Kind1 LotId_Kind1 Value_Kind1 Kind_Kind1 attributeid_Kind2 LotId_Kind2 Value_Kind2 Kind_Kind2 attributeid_Kind3 LotId_Kind3 Value_Kind3 Kind_Kind3
----------- -------- ----------------- ----------- ----------- ---------- ----------------- ----------- ----------- ---------- ----------------- ----------- ----------- ----------
1 WithAll 1 1 Foo1 Kind1 2 1 Foo2 Kind2 3 1 Foo3 Kind3
2 Hello NULL NULL NULL NULL 10 2 Bar2 Kind2 NULL NULL NULL NULL
3 World NULL NULL NULL NULL NULL NULL NULL NULL 12 3 Bar3 Kind3
因为KindX
在Kind_x
列中,等等。
声明 @Lot 表 ( LotId INT 主键标识, SomeText VARCHAR(8)) 插入@Lot 值('WithAll'),('Hello'),('World') 声明@属性表( AttributeId INT 主键标识, LotId INT, 瓦尔 VARCHAR(8), 类型 VARCHAR(8)) 插入@Attribute 值 (1, 'Foo1', 'Kind1'), (1, 'Foo2', 'Kind2'), (1, 'Foo3', 'Kind3'), (1, 'Foo4', 'Kind4'), (1, 'Foo5', 'Kind5'), (1, 'Foo6', 'Kind6'), (1, 'Foo7', 'Kind7'), (1, 'Foo8', 'Kind8'), (1, 'Foo9', 'Kind9'), (2, 'Bar2', 'Kind2'), (2, 'Bar1', 'Kind8'), (3,'Bar3','Kind3') 声明@AttributesMask 表( 类型 VARCHAR(8) ) 插入@AttributesMask 值('Kind1'),('Kind2'),('Kind3'),('Kind4'),('Kind5'),('Kind6'),('Kind7'),('Kind8') 选择 * 从( 选择 LotId, 一些文本, --col+'_'+CAST(rn as varchar(10)) col, col+'_'+[种类] col, 价值 从 ( 选择 l.LotId, l.SomeText, cast(a.AttributeId as varchar(8)) 属性id, cast(a.LotId as varchar(8)) a_LotId, a.Val, 一种 --, ROW_NUMBER() over(partition by l.[LotId] order by am.[Kind]) rn FROM @AttributesMask 作为我 LEFT 在 [am].[Kind] = [a].[Kind] 上加入 @Attribute a LEFT JOIN @Lot l ON [a].[LotId] = [l].[LotId] ) 源代码 交叉申请 ( values ('attributeid', attributeid),('LotId', a_LotId), ('Value', Val), ('Kind', Kind) ) c (col, 值) ) d PIVOT (max(value) for col in ( 属性id_Kind1、LotId_Kind1、Value_Kind1、Kind_Kind1、 属性id_Kind2、LotId_Kind2、Value_Kind2、Kind_Kind2、 attributeid_Kind3、LotId_Kind3、Value_Kind3、Kind_Kind3)) piv 按批次订购
为了获得正确的结果,我使用掩码预先排列了 PIVOT 来源的数据。不戴口罩怎么办?
参考问题:How to replace a functional (many) OUTER APPLY (SELECT * FROM)