将键值数据透视到行

时间:2019-06-03 21:17:33

标签: sql sql-server tsql sql-server-2016

我在表中具有“键-值”配对格式的数据-对于每个Id,您可以有多个key/value配对值,并带有指定表值的附加列。

数据表:

ID    Table  Key     Value
--    --     --      --
221   Tab1   Field2  Jon
221   Tab1   Field5  Snow
221   Tab1   Field4  Male
221   Tab1   Field3  Pass
2256  Tab1   Field2  Jil
2256  Tab1   Field5  Dark

Key列中的数据是指“表”列中(表)数据所引用的实际列名。

现在,我要透视此数据,以使每个ID在相关表中仅表示为一行,并将数据复制到适当的列:

Tab1:

Id   Field1 Field2  Field3  Field4  Field5  Field6
--   --     --      --      --      --      --
221         Jon     Pass    Male    Snow
2256        Jil                     Dark

我该如何写呢?

1 个答案:

答案 0 :(得分:2)

首先,示例DDL / DML语句:

CREATE TABLE t (ID INT, [Table] VARCHAR(5), [Key] varchar(6), Value varchar(5))
INSERT INTO t VALUES (221, 'Tab1', 'Field2', 'Jon'),
(221 ,'Tab1','Field5','Snow'),
(221 ,'Tab1','Field4','Male'),
(221 ,'Tab1','Field3','Pass'),
(2256,'Tab1','Field2','Jil '),
(2256,'Tab1','Field5','Dark')

具有硬编码列的静态数据透视查询如下所示:

SELECT *
FROM t 
PIVOT (MAX(Value) FOR [Key] IN ([Field1], [Field2], [Field3], [Field4], [Field5], [Field6]))p

返回:

ID      Table   Field1  Field2  Field3  Field4  Field5  Field6
221     Tab1    NULL    Jon     Pass    Male    Snow    NULL
2256    Tab1    NULL    Jil     NULL    NULL    Dark    NULL

如果您需要根据数据动态确定列,这是使用sp_executesql的一种方法:

DECLARE @sql NVARCHAR(MAX)
SELECT @sql = N'
SELECT p.*
FROM t
PIVOT (MAX(Value) FOR [Key] IN (' + 
    STUFF((SELECT DISTINCT ',' + QUOTENAME([Key]) FROM t FOR XML PATH('')), 1, 1, '') + '))p
'
EXEC sp_executesql @sql

返回:

ID      Table   Field2  Field3  Field4  Field5
221     Tab1    Jon     Pass    Male    Snow
2256    Tab1    Jil     NULL    NULL    Dark

此行:

SELECT STUFF((SELECT DISTINCT ',' + QUOTENAME([Key]) FROM t FOR XML PATH('')), 1, 1, '')

将括号括起来并在该字符串中定界:

[Field2],[Field3],[Field4],[Field5]