0

属性を持つテーブル(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を使用UNPIVOTPIVOTて、次の形式でデータを取得しています。

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

SQLフィドル

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

SQLフィドル

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)を置き換える方法

4

1 に答える 1

0

私があなたの説明に何かを逃していない限り、あなたは必要ありませんAttributeMask。最終的な列名が元の列名になり、次にKind値になる場合は、次を使用できます。

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;

SQL FiddlewithDemoを参照してください。これにより、次の結果が得られます。

| 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 |
于 2013-03-13T22:17:33.520 に答える