具有动态列的Pivot TSQL表

具有动态列的Pivot TSQL表,sql,sql-server,json,Sql,Sql Server,Json,我将JSON作为参数传递给SQL存储过程。我使用一个函数,该函数接受一个JSON字典,并创建一个表,其中包含两列的键值对,然后与COALESCE一起使用,为INSERT语句创建动态sql。这对于单个字典很好,但我还需要能够发送包含字典数组的JSON字符串。现在,我的parse函数给了我这个表变量: 我需要的是这样一个表变量: 我可以使用以下命令从第一个表中获取列名: SELECT DISTINCT element name from @JSONTable 我应该提到的是,这些元素名称可以而且将

我将JSON作为参数传递给SQL存储过程。我使用一个函数,该函数接受一个JSON字典,并创建一个表,其中包含两列的键值对,然后与COALESCE一起使用,为INSERT语句创建动态sql。这对于单个字典很好,但我还需要能够发送包含字典数组的JSON字符串。现在,我的parse函数给了我这个表变量:

我需要的是这样一个表变量:

我可以使用以下命令从第一个表中获取列名:

SELECT DISTINCT element name from @JSONTable
我应该提到的是,这些元素名称可以而且将会改变。我不知道不同elementname值的数量

更新-使用Umair的答案,我正在接近:

DECLARE @JSONString AS VARCHAR(MAX)

SET @JSONString = '[{"ravid":3,"ravversion":2,"taskid":3},{"ravid":4,"ravversion":7,"taskid":99}]'

IF OBJECT_ID('tempdb..#JSONTable') IS NOT NULL
    DROP TABLE #JSONTable


CREATE TABLE #JSONTable
            (
              elementname VARCHAR(500) ,
              elementvalue VARCHAR(500)
            )
        INSERT  INTO #JSONTable
                ( elementname ,
                  elementvalue

                )
                SELECT  NAME ,
                        StringValue
                FROM    dbo.parseJSON(@JSONString)
                WHERE   LEN(StringValue) > 0 AND NAME IS NOT NULL



--declare a csv variable with all the distinct elements
DECLARE @csv NVARCHAR(max) = STUFF(
    (
         SELECT ',' + elementname
         FROM (
              SELECT DISTINCT elementname
              FROM #JSONTable
         ) AS e
         FOR XML PATH(''), TYPE
    ).value('.', 'nvarchar(max)'),
    1,
    1,
    ''
);

DECLARE @sql NVARCHAR(MAX) = '
    SELECT *
    FROM (
       SELECT *, Row = ROW_NUMBER() OVER (PARTITION BY elementname ORDER BY elementname)
       FROM #JSONTable
    ) AS t
    PIVOT (
        MAX(elementvalue)
        FOR elementname IN (' + @csv + ')
    ) AS p
'

EXEC sp_executesql @sql
但是字典值与键不对应。以下是Umair当前回答的结果: 怎么样

--declare a csv variable with all the distinct elements
DECLARE @csv NVARCHAR(max) = STUFF(
    (
         SELECT ',' + elementname
         FROM (
              SELECT DISTINCT elementname
              FROM #JSONTable
         ) AS e
         FOR XML PATH(''), TYPE
    ).value('.', 'nvarchar(max)'),
    1,
    1,
    ''
);

DECLARE @sql NVARCHAR(MAX) = '
    SELECT *
    FROM (
       SELECT *, Row = ROW_NUMBER() OVER (PARTITION BY elementname ORDER BY elementvalue)
       FROM #JSONTable
    ) AS t
    PIVOT (
        MAX(elementvalue)
        FOR elementname IN (' + @csv + ')
    ) AS p
'

EXEC sp_executesql @sql
i、 e动态旋转:

编辑:


由于您不希望通过透视中的任何内容进行聚合,因此我添加了一个row number函数,以根据元素值为每个不同的elementname分配一个顺序递增的id。这将基本上按照该行列对数据透视进行分组,生成所有必需的行。

动态SQL不知道@JSONTable变量。我在问题中添加了我现在使用的SQL,包括您建议的SQL。应该能够。让我举一个例子,我得到了另一个错误-Msg 102,15级,状态1,第7行附近语法不正确。当sp_executesql命令运行时,这是为sp_executesql生成的SQL-从JSONTable中选择*作为ravid、ravversion、taskid中elementname的j PIVOT MAXelementvalue非常感谢您的帮助。我更新了我的答案以包括你的最新答案。我们越来越近了。现在的值与键不匹配,有什么想法吗?注意-为了测试,我更改了传入JSON的值。我非常确定parseJSON函数工作正常。它给了我一个包含所有键和值的SQL表。这个问题来自于关键部分。你不太明白我在说什么。parseJSON函数解析json字符串的方式没有问题。但信息正在丢失,特别是密钥与哪个对象关联。示例:[{property1:'value1',property2:'value2'},{'property3':'value3'}]和[{property1:'value1'},{'property2':'value2',property3:'value3'}]将在函数中产生相同的输出。那么,如何区分每个键属于哪个对象呢?唯一的方法是在函数中添加一个新列。它指示密钥属于哪个对象。获取。我将开始回顾我正在使用的UDF。谢谢。