属性を持つテーブル(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_1
Kind3
Kind_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)を置き換える方法