将键值列分组为每组行,每个键列

Group key-value columns into a rows per group with column per key

我需要在 table 的 MS SQL 数据库中显示包含 n 个键的 key/value 对组,每组一个记录,每个键一列。

我找到了那个例子,但在我的例子中,键(最后是列)没有修复,必须也来自数据库。

示例:

CREATE TABLE entries
    ([group_id] int, [attr_key] varchar(20), [attr_value] varchar(20))
;

INSERT INTO entries
   ([group_id], [attr_key], [attr_value])

VALUES
   (1, 'color', 'blue'),
   (1, 'size', 'L'),
   (2, 'color', 'red'),
   (2, 'size', 'M'),
   (3, 'color', 'green'),
   (3, 'size', 'M'),
   (3, 'Vendor', 'myVendor') ,
   (3, 'picture', 'Bear') 
;

在 Fiddle 中测试:http://sqlfiddle.com/#!18/c1ff2/1/0

| group_id | attr_key | attr_value |
|----------|----------|------------|
|        1 |    color |       blue |
|        1 |     size |          L |
|        2 |    color |        red |
|        2 |     size |          M |
|        3 |    color |      green |
|        3 |     size |          M |
|        3 |   vendor |   myVendor |
|        3 |  picture |       Bear |

结果应如下所示:

| group_id | color | size | vendor   | picture | 
|----------|-------|------|----------|---------|
|        1 | blue  |  L   | NULL     |  NULL   |
|        2 | red   |  M   | NULL     |  NULL   |
|        3 | green |  M   | myVendor |  Bear   |

稍后用户添加属性时,table 也应该多一列,而无需更改 SQL 查询。

DECLARE  @entries TABLE
    ([group_id] int, [attr_key] varchar(20), [attr_value] varchar(20))
;

INSERT INTO @entries
    ([group_id], [attr_key], [attr_value])
VALUES
    (1, 'color', 'blue'),
    (1, 'size', 'L'),
    (2, 'color', 'red'),
    (2, 'size', 'M'),
    (3, 'color', 'green'),
    (3, 'size', 'M'),
    (3, 'Vendor', 'myVendor') ,
    (3, 'picture', 'Bear')

;

SELECT * FROM (
SELECT * 
FROM @entries
) AS A
PIVOT (MAX([attr_value]) FOR [attr_key] IN ([color],[size],[Vendor],[picture])) AS P

输出

group_id    color   size    Vendor  picture
1           blue    L       NULL    NULL
2           red     M       NULL    NULL
3           green   M      myVendor Bear

对于数量不固定的属性,您应该使用动态数据透视表

declare @columns varchar(max)
declare @sql varchar(max)

set @columns = stuff((select ',' + quotename(attr_key) from entries
group by attr_key
for xml path('')), 1, 1, '')

set @sql = '
    select
        group_id, ' + @columns + '
    from
        entries
    pivot (
        max(attr_value) for attr_key in (' + @columns + ')
    ) p'


exec (@sql)