想象一个带有属性的表(键值)和带有很多的父表。
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_1Kind3Kind_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)