【问题标题】:Pivot key value data to row将键值数据透视到行
【发布时间】:2019-06-03 21:17:33
【问题描述】:

我的表格中有一个“键值”配对格式的数据 - 对于每个 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 仅表示为相关表中的一行,并将数据复制到相应的列:

表 1:

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

我该如何写这篇文章?

【问题讨论】:

  • 考虑到您没有值为Field6 的行但有一个列,这表明您的值数量不确定;正确的?您是否查找过动态 Pivot? Stack Overflow 上有很多关于如何使用它们的示例。你能告诉我们你的尝试吗?
  • 这种整体风格被称为entity-attribute-value,并且可能会受到严重的惩罚,即使(或特别是)实施得当。您可能需要重新评估您是否真的拥有如此稀疏的数据集。

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


【解决方案1】:

首先,示例 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]

【讨论】:

  • 谢谢,在构建我的解决方案时非常有用。我并入动态sql来实现。很棒的马克斯。
  • @Sandiyan 太棒了!你能接受答案吗?谢谢。
猜你喜欢
  • 2020-09-28
  • 1970-01-01
  • 2016-01-23
  • 1970-01-01
  • 1970-01-01
  • 2018-06-18
  • 2016-01-11
  • 1970-01-01
  • 2015-08-27
相关资源
最近更新 更多