当前位置: 首页 > 知识库问答 >
问题:

表的分层JSON输出

邴和雅
2023-03-14

我有这个桌子结构

| User | Type    | Data |
|------|---------|------|
| 1    | "T1"    | "A"  |
| 1    | "T1"    | "B"  |
| 1    | "T2"    | "C"  |
| 2    | "T1"    | "D"  |

我想从我的查询中得到一个层次化的JSON字符串

{
  "1": {
    "T1": [
      "A",
      "B"
    ],
    "T2": [
      "C"
    ]
  },
  "2": {
    "T1": [
      "D"
    ]
  }
}

因此,每个用户有一个条目,每个类型有一个子条目,然后每个数据有一个子条目

我只找到了JSON路径的、ROOT('x')AUTO语句,但没有任何东西可以使这个层次化。这可能是开箱即用的吗?我找不到任何东西,所以我尝试了(递归)CTE,但没走多远。如果有人能为我指出正确的方向,我将不胜感激。

共有2个答案

鲜于光辉
2023-03-14

这并不是你想要的(我对JSON不太在行),但它确实能让你接近你需要的形状,直到更好的东西出现(https://jsonformatter.org/json-parser/974b6b)

use tempdb
GO

drop table if exists users
create table users (
    [user] integer
    , [type] char(2)
    , [data] char(1)
)


insert into users 
values (1, 'T1', 'A')
    , (1, 'T1', 'B')
    , (1, 'T2', 'C')
    , (2, 'T1', 'D')

select DISTINCT ONE.[user], two.[type], three.[data] 
from users AS ONE
inner join users two
    on one.[user] = two.[user]
inner join users three
    on one.[user] = three.[user]
    and two.[type] = three.[type]
for JSON AUTO
慕容高卓
2023-03-14

我不确定您是否可以使用FOR JSON AUTOFOR JSON PATH创建具有可变键名称的JSON。我建议以下解决方案:

  • 使用XML路径生成JSON,并进行字符串操作

表:

CREATE TABLE #InputData (
   [User] int,
   [Type] varchar(2),
   [Data] varchar(1)
)
INSERT INTO #InputData 
   ([User], [Type], [Data])
VALUES
   (1, 'T1', 'A'),
   (1, 'T1', 'B'),
   (1, 'T2', 'C'),
   (2, 'T1', 'D')

对XML路径使用的语句:

;WITH SecondLevelCTE AS (
   SELECT 
      d.[User],
      d.[Type],
      Json1 = CONCAT(
         '[', 
         STUFF(
         (
         SELECT CONCAT(',"', [Data], '"')
         FROM #InputData 
         WHERE [User] = d.[User] AND [Type] = d.[Type]
         FOR XML PATH('')
         ), 1, 1, ''),
         ']')
   FROM #InputData d
   GROUP BY d.[User], d.[Type]
), FirstLevelCTE AS (
   SELECT 
      d.[User],
      Json2 = CONCAT(
         '{',
         STUFF(
         (
         SELECT CONCAT(',"', [Type], '":', [Json1])
         FROM SecondLevelCTE 
         WHERE [User] = d.[User]
         FOR XML PATH('')
         ), 1, 1, ''),
         '}'
      )
   FROM SecondLevelCTE d
   GROUP BY d.[User]
)
SELECT CONCAT(
   '{',
   STUFF(
   (
   SELECT CONCAT(',"', [User], '":', Json2)
   FROM FirstLevelCTE
   FOR XML PATH('')
   ), 1, 1, '')   ,
   '}'
)

使用字符串AGG()的语句:

;WITH SecondLevelCTE AS (
   SELECT 
      d.[User],
      d.[Type],
      Json1 = (
         SELECT CONCAT('["', STRING_AGG([Data], '","'), '"]')
         FROM #InputData 
         WHERE [User] = d.[User] AND [Type] = d.[Type]
      )
   FROM #InputData d
   GROUP BY d.[User], d.[Type]
), FirstLevelCTE AS (
   SELECT 
      d.[User],
      Json2 = (
         SELECT STRING_AGG(CONCAT('"', [Type], '":', [Json1]), ',')
         FROM SecondLevelCTE
         WHERE [User] = d.[User]
      )
   FROM SecondLevelCTE d
   GROUP BY d.[User]
)
SELECT CONCAT('{', STRING_AGG(CONCAT('"', [User], '":{', Json2, '}'), ','), '}')
FROM FirstLevelCTE

使用STRING_AGG()JSON_MODIFY()的语句:

DECLARE @json nvarchar(max) = N'{}'
SELECT 
   @json = JSON_MODIFY(
      CASE 
         WHEN JSON_QUERY(@json, CONCAT('$."', [User] , '"')) IS NULL THEN JSON_MODIFY(@json, CONCAT('$."', [User] , '"'), JSON_QUERY('{}'))
         ELSE @json
      END,
      CONCAT('$."', [User] , '".', [Type]), 
      JSON_QUERY(Json)
   )
FROM (
   SELECT 
      d.[User],
      d.[Type],
      Json = (
         SELECT CONCAT('["', STRING_AGG([Data], '","'), '"]')
         FROM #InputData 
         WHERE [User] = d.[User] AND [Type] = d.[Type]
      )
   FROM #InputData d
   GROUP BY d.[User], d.[Type]
) t

输出:

{"1":{"T1":["A","B"],"T2":["C"]},"2":{"T1":["D"]}}

 类似资料:
  • 本文向大家介绍MongoDB 中创建分层JSON,包括了MongoDB 中创建分层JSON的使用技巧和注意事项,需要的朋友参考一下 使用以下语法在MongoDB中创建分层JSON- 让我们创建一个包含文档的集合- 在find()方法的帮助下显示集合中的所有文档- 这将产生以下输出-

  • 我在Postgres数据库中有一个分层表,例如,

  • 我有一个火花数据框,我需要写入MongoDB。我想知道如何在mongoDB中将数据框的一些列写成嵌套/分层JSON。假设数据框有6列,col1,col2,…… col5,col6我想要col1,col2,col3作为第一层次结构,其余列col4到col6作为第二层次结构。像这样的东西, 我如何在pyspark中实现这一点?

  • 我有一个父子关系数据库。数据如下所示,但可以以任何方式呈现(字典、列表列表、JSON等)。 我需要的输出是一个层次化的JSON树,它将用d3呈现。数据中有离散的子树,我将附加到根节点。所以我需要递归地遍历链接,并建立树结构。我最多只能遍历所有人并附加他们的孩子,但我不知道如何进行高阶链接(例如,如何将有孩子的人附加到其他人的孩子)。这类似于这里的另一个问题,但我无法提前知道根节点,因此无法实现公认

  • 问题内容: http://jsfiddle.net/eYgGK/ 我从另一个帖子中偷走了这个脚本: 该脚本产生: 我正在寻找的是: 我首先需要摆脱“值”包装,其次是空的子节点。我知道我可以编写一个清理脚本,但是那不是最佳实践。如果有人知道如何修复或建议其他脚本,那就太好了! 谢谢 问题答案: 尝试类似的东西 演示:小提琴 结果

  • 问题内容: 我在将选项卡中的JSON输出到HTML表时遇到了麻烦(这是javascript / jQuery夜间课程分配的一部分)。请有人看看,并建议我要对表格格式的输出进行哪些修改?我收到成功警报,但表未填充。 谢谢。 和HTML: 问题答案: 代码的主要问题是,在AJAX请求成功完成后,您没有调用任何函数。您至少需要致电才能填充数据。 但是,您可以对代码进行一些改进。首先,删除。这是默认值,并