属性を持つテーブル(key-value)と、ロットを持つ親テーブルを想像してみてください。
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
私は--operationを使用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
なんで?
列とのKind2テキストのため。Kind_1Kind3Kind_2
DECLARE @Lot TABLE(
LotId INT PRIMARY KEY IDENTITY、
SomeText VARCHAR(8))
@Lotに挿入
VALUES('Hello')、('World')
DECLARE @Attribute TABLE(
AttributeId INT PRIMARY KEY IDENTITY、
LotId INT、
Val VARCHAR(8)、
種類VARCHAR(8))
@AttributeVALUESに挿入
(2、'Bar2'、'Kind2')、
(2、'Bar1'、'Kind8')、
(2、'Bar3'、'Kind3')、
(1、'Foo1'、'Kind1')
選択する *
から
((
LotIdを選択し、
SomeText、
col +'_' + CAST(rn as varchar(10))col、
価値
から
((
l.LotIdを選択し、
l.SomeText、
cast(a.AttributeId as varchar(8))attributeid、
cast(a.LotId as varchar(8))a_LotId、
a.Val、
a。種類、
ROW_NUMBER()over(partition by l.lotid order by a.kind)rn
@Lotlから
左参加@属性a
l.LotId=a.LotIdで
)src
クロスアプライ
((
値('attributeid'、attributeid)、('LotId'、a_LotId)、('Value'、Val)、('Kind'、Kind)
)c(col、value)
)d
ピボット
((
max(value)
col in(attributeid_1、LotId_1、Value_1、Kind_1、
attributeid_2、LotId_2、Value_2、Kind_2、
attributeid_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
DECLARE @Lot TABLE(
LotId INT PRIMARY KEY IDENTITY、
SomeText VARCHAR(8))
@Lotに挿入
VALUES('WithAll')、('Hello')、('World')
DECLARE @Attribute TABLE(
AttributeId INT PRIMARY KEY IDENTITY、
LotId INT、
Val VARCHAR(8)、
種類VARCHAR(8))
@AttributeVALUESに挿入
(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(
種類VARCHAR(8)
)。
INSERT INTO @AttributesMask
VALUES('Kind1')、('Kind2')、('Kind3')、('Kind4')、('Kind5')、('Kind6')、('Kind7')、('Kind8')
select * from(
LotIdを選択し、
SomeText、
--col +'_' + CAST(rn as varchar(10))col、
col +'_' + [Kind] col、
価値
から
((
l.LotIdを選択し、
l.SomeText、
cast(a.AttributeId as varchar(8))attributeid、
cast(a.LotId as varchar(8))a_LotId、
a.Val、
a。種類
-、ROW_NUMBER()over(partitionbyl。[LotId]orderby am。[Kind])rn
FROM @AttributesMask AS am
[am]。[Kind]=[a]。[Kind]の左結合@Attributea
LEFT JOIN @Lot lON[a]。[LotId]=[l]。[LotId]
)src
クロスアプライ
((
値('attributeid'、attributeid)、('LotId'、a_LotId)、('Value'、Val)、('Kind'、Kind)
)c(col、value)
)d PIVOT(col in(のmax(value))
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で注文する
正しい結果を得るために、私はマスクを使用して、PIVOTのソースであるデータを事前に配置しました。マスクなしでそれを行う方法は?
質問を参照してください:機能的な(多くの)OUTER APPLY(SELECT * FROM)を置き換える方法