如何使用行中的值按行构造JSON SQL?

如何使用行中的值按行构造JSON SQL?,sql,json,sql-server,Sql,Json,Sql Server,我正在努力使用SQL构造JSON 假设我有一张这样的桌子: | col1 | col2 | col3 | +---------------+----------+----------+ | specialvalue | someval | someval | | specialvalue2 | someval2 | someval2 | | | | | 我试图得到如下结构: { "s

我正在努力使用SQL构造JSON

假设我有一张这样的桌子:

| col1          | col2     | col3     |
+---------------+----------+----------+
| specialvalue  | someval  | someval  |
| specialvalue2 | someval2 | someval2 |
|               |          |          |
我试图得到如下结构:

{
    "specialvalue": {
        "specialcol": "specialvalue",
        "col2": "someval",
        "col3": "someval"
    },
    "specialvalue2": {
        "specialcol": "specialvalue2",
        "col2": "someval2",
        "col3": "someval2"
    }
}
SELECT
     specialcol,
     col2,
     col3
INTO #tmpTbl
FROM myTable

SELECT 
    specialcol, 
    (SELECT * FROM #tmpTbl FOR JSON AUTO) as 'Value' 
FROM #tmpTbl 
FOR JSON AUTO

DROP TABLE #tmp
{
    "specialcol":"specialvalue",
    "Value":{
        "col1": "specialvalue",
        "col2": "someval",
        "col3": "someval"
    },
    "specialcol":"specialvalue2",
    "Value":{
        "col1": "specialvalue2",
        "col2": "someval2",
        "col3": "someval2"
    }
}
我怎样才能做到这一点?在映射集合中的每一行时,我可以使用JSON_MODIFY和动态键吗

我得到的最接近的结果如下:

{
    "specialvalue": {
        "specialcol": "specialvalue",
        "col2": "someval",
        "col3": "someval"
    },
    "specialvalue2": {
        "specialcol": "specialvalue2",
        "col2": "someval2",
        "col3": "someval2"
    }
}
SELECT
     specialcol,
     col2,
     col3
INTO #tmpTbl
FROM myTable

SELECT 
    specialcol, 
    (SELECT * FROM #tmpTbl FOR JSON AUTO) as 'Value' 
FROM #tmpTbl 
FOR JSON AUTO

DROP TABLE #tmp
{
    "specialcol":"specialvalue",
    "Value":{
        "col1": "specialvalue",
        "col2": "someval",
        "col3": "someval"
    },
    "specialcol":"specialvalue2",
    "Value":{
        "col1": "specialvalue2",
        "col2": "someval2",
        "col3": "someval2"
    }
}
返回以下内容:

{
    "specialvalue": {
        "specialcol": "specialvalue",
        "col2": "someval",
        "col3": "someval"
    },
    "specialvalue2": {
        "specialcol": "specialvalue2",
        "col2": "someval2",
        "col3": "someval2"
    }
}
SELECT
     specialcol,
     col2,
     col3
INTO #tmpTbl
FROM myTable

SELECT 
    specialcol, 
    (SELECT * FROM #tmpTbl FOR JSON AUTO) as 'Value' 
FROM #tmpTbl 
FOR JSON AUTO

DROP TABLE #tmp
{
    "specialcol":"specialvalue",
    "Value":{
        "col1": "specialvalue",
        "col2": "someval",
        "col3": "someval"
    },
    "specialcol":"specialvalue2",
    "Value":{
        "col1": "specialvalue2",
        "col2": "someval2",
        "col3": "someval2"
    }
}
这很接近,但不是我所需要的

有没有一种方法可以使用JSON_MODIFY来实现我想要的功能?

SQL Server 2017-

;WITH cte as (
select 'specialvalue'  as specialcol,  'someval'  col2, 'someval'  col3 union 
select 'specialvalue2' as specialcol,  'someval2' col2, 'someval2' col3 )
SELECT 
CASE WHEN specialcol = 'specialvalue' THEN specialcol END as [specialvalue.specialcol],
CASE WHEN specialcol = 'specialvalue' THEN col2 END as [specialvalue.col2],
CASE WHEN specialcol = 'specialvalue' THEN col3 END as [specialvalue.col3],
CASE WHEN specialcol = 'specialvalue2' THEN specialcol END as [specialvalue2.specialcol],
CASE WHEN specialcol = 'specialvalue2' THEN col2 END as [specialvalue2.col2],
CASE WHEN specialcol = 'specialvalue2' THEN col3 END as [specialvalue2.col3]
FROM cte
FOR JSON PATH
输出:


从我的评论和思考中。这不是最优雅的,但可能会让你达到目的

内联查询以json格式获取结果,然后根据col1中的值将这些结果包装为键。把它们放在一起,用逗号分隔,最后用括号括起来

DECLARE @TestData TABLE
    (
        [col1] NVARCHAR(100)
      , [col2] NVARCHAR(100)
      , [col3] NVARCHAR(100)
    );

DECLARE @JsonValue NVARCHAR(MAX) = '';

INSERT INTO @TestData (
                          [col1]
                        , [col2]
                        , [col3]
                      )
VALUES ( 'specialvalue', 'someval', 'someval' )
     , ( 'specialvalue2', 'someval2', 'someval2' );


SELECT @JsonValue = @JsonValue + N'"' + [a].[col1] + N'": '
                    + (
                          SELECT [aa].[col1] AS 'specialvalue'
                               , [aa].[col2] AS 'col2'
                               , [aa].[col3] AS 'col3'
                          FROM   @TestData [aa]
                          WHERE  [aa].[col1] = [a].[col1]
                          FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
                      ) + N','
FROM   @TestData [a];

SET @JsonValue = N'{' + SUBSTRING(@JsonValue, 1, LEN(@JsonValue) - 1) + N'}';
SELECT @JsonValue;
给你这个:

{
  "specialvalue": {
    "specialvalue": "specialvalue",
    "col2": "someval",
    "col3": "someval"
  },
  "specialvalue2": {
    "specialvalue": "specialvalue2",
    "col2": "someval2",
    "col3": "someval2"
  }
}

这不是一个可行的解决方案-您实际上只是硬编码了我在示例中提供的键“specialvalue”和“specialvalue 2”。这些值可以是任何值,我不能使用硬编码值作为键。我不这么认为。您可以通过对已有的FOR JSON进行一些调整来接近它,但是当您需要基于col1中的值来命名它时,您的顶级键最终会被命名为相同的。不完全相同,但情况相似,他们最终没有使用JSON,我喜欢它。我的意思是,这确实有点骇客,但我能想到的其他解决方案是执行动态sql和遍历临时表,这也很骇客,但性能很差。这是一种更简单、更有效的方法。谢谢