0

想象一个带有属性的表(键值)和带有很多的父表。

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

SQL小提琴

声明 @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

因为KindXKind_x列中,等等。

SQL小提琴

声明 @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)

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 Fiddle with Demo。这给出了结果:

| 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 回答