Sql server 为数据透视源排序数据
假设一个表键值具有属性,父表具有批次Sql server 为数据透视源排序数据,sql-server,sql-server-2008,pivot,unpivot,Sql Server,Sql Server 2008,Pivot,Unpivot,假设一个表键值具有属性,父表具有批次 LotId SomeText ----------- -------- 1 Hello 2 World AttributeId LotId Val Kind ----------- ----------- -------- -------- 1 1 Foo1 Kind1 2 1 Foo2
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
如何选择与属性表的值无关的数据
错误结果的示例:
为什么?
因为Kind2文本位于Kind1列,Kind3位于Kind2列
因为KindX在Kind\u x列中,等等
为了得到正确的结果,我使用了掩码来预先安排作为PIVOT源的数据。没有面具怎么办
关于这个问题:除非我在你的解释中遗漏了什么,否则你不需要属性掩码。如果最终列名只是原始列名,然后是种类值,则可以使用:
select *
from
(
select LotId,
SomeText,
col+'_'+Kind col,
value
from
(
select l.LotId,
l.SomeText,
cast(a.AttributeId as varchar(8)) attributeid,
cast(a.LotId as varchar(8)) a_LotId,
a.Val,
a.Kind
from @Lot l
left join @Attribute a
on l.LotId = a.LotId
) src
cross apply
(
values ('attributeid', attributeid),('LotId', a_LotId), ('Value', Val), ('Kind', Kind)
) c (col, value)
) d
pivot
(
max(value)
for col in (attributeid_Kind1, LotId_Kind1, Value_Kind1, Kind_Kind1,
attributeid_Kind2, LotId_Kind2, Value_Kind2, Kind_Kind2,
attributeid_Kind3, LotId_Kind3, Value_Kind3, Kind_Kind3)
) 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 |
有时候我在寻找一个问题,但我还有另一个挑战。我需要添加一些逻辑,比如CASE,那么这次外部应用是合理的吗@Tomasito请在新问题中发布新问题:我们开始
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
DECLARE @Lot TABLE (
LotId INT PRIMARY KEY IDENTITY,
SomeText VARCHAR(8))
INSERT INTO @Lot
VALUES ('WithAll'), ('Hello'), ('World')
DECLARE @Attribute TABLE(
AttributeId INT PRIMARY KEY IDENTITY,
LotId INT,
Val VARCHAR(8),
Kind VARCHAR(8))
INSERT INTO @Attribute VALUES
(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')
DECLARE @AttributesMask TABLE(
Kind VARCHAR(8)
)
INSERT INTO @AttributesMask
VALUES('Kind1'), ('Kind2'), ('Kind3'), ('Kind4'), ('Kind5'), ('Kind6'), ('Kind7'), ('Kind8')
select * from(
select LotId,
SomeText,
--col+'_'+CAST(rn as varchar(10)) col,
col+'_'+[Kind] col,
value
from
(
select l.LotId,
l.SomeText,
cast(a.AttributeId as varchar(8)) attributeid,
cast(a.LotId as varchar(8)) a_LotId,
a.Val,
a.Kind
--, ROW_NUMBER() over(partition by l.[LotId] order by am.[Kind]) rn
FROM @AttributesMask AS am
LEFT join @Attribute a on [am].[Kind] = [a].[Kind]
LEFT JOIN @Lot l ON [a].[LotId] = [l].[LotId]
) src
cross apply
(
values ('attributeid', attributeid),('LotId', a_LotId), ('Value', Val), ('Kind', Kind)
) c (col, value)
) d PIVOT (max(value) for col in (
attributeid_Kind1, LotId_Kind1, Value_Kind1, Kind_Kind1,
attributeid_Kind2, LotId_Kind2, Value_Kind2, Kind_Kind2,
attributeid_Kind3, LotId_Kind3, Value_Kind3, Kind_Kind3)) piv
ORDER BY LotId
select *
from
(
select LotId,
SomeText,
col+'_'+Kind col,
value
from
(
select l.LotId,
l.SomeText,
cast(a.AttributeId as varchar(8)) attributeid,
cast(a.LotId as varchar(8)) a_LotId,
a.Val,
a.Kind
from @Lot l
left join @Attribute a
on l.LotId = a.LotId
) src
cross apply
(
values ('attributeid', attributeid),('LotId', a_LotId), ('Value', Val), ('Kind', Kind)
) c (col, value)
) d
pivot
(
max(value)
for col in (attributeid_Kind1, LotId_Kind1, Value_Kind1, Kind_Kind1,
attributeid_Kind2, LotId_Kind2, Value_Kind2, Kind_Kind2,
attributeid_Kind3, LotId_Kind3, Value_Kind3, Kind_Kind3)
) 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 |