繁体   English   中英

带有动态列的数据透视TSQL表

[英]Pivot TSQL table with dynamic columns

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

在此处输入图片说明

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

在此处输入图片说明

我可以从第一个表中获取列名称:

SELECT DISTINCT element name from @JSONTable

我应该提到,这些elementname可以并且将会改变。 我将不知道不同的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

即动态枢轴:)

编辑:

由于您不希望通过数据透视表中的任何内容进行聚合,因此我添加了一个行号功能,为每个不同的elementname分配一个按顺序递增的id(基于element值)。 这实际上将按此行列将数据透视表分组,从而生成所有必需的行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM