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

时间:2018-02-16 09:43:36

标签: sql sql-server key-value relational relational-division

我需要在一个表中显示存储在MS SQL数据库中的n个键的键/值对组,每个组一个记录,每个键一个列。

我发现了这个例子,但在我的情况下,键(最后是列)没有修复,也必须来自数据库。 Group key-value columns into a single row

示例:

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') 
;

小提琴测试: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   |

稍后,当用户添加属性时,该表还应该有一列,而不会更改SQL查询。

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

您应该将动态数据透视用于不定数量的属性

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)