我需要从一个查询创建一个JSON输出,该查询使用具有一对多关系的两个表之间的内连接 我希望将辅助表的值嵌套为主表的数组属性。
考虑以下示例:
DECLARE @Persons AS TABLE
(
person_id int primary key,
person_name varchar(20)
)
DECLARE @Pets AS TABLE
(
pet_owner int, -- in real tables, this would be a foreign key
pet_id int primary key,
pet_name varchar(10)
)
INSERT INTO @Persons (person_id, person_name) VALUES
(2, 'Jack'),
(3, 'Jill')
INSERT INTO @Pets (pet_owner, pet_id, pet_name) VALUES
(2, 4, 'Bug'),
(2, 5, 'Feature'),
(3, 6, 'Fiend')
并查询:
DECLARE @Result as varchar(max)
SET @Result =
(
SELECT person_id as [person.id],
person_name as [person.name],
pet_id as [person.pet.id],
pet_name as [person.pet.name]
FROM @Persons
JOIN @Pets ON person_id = pet_owner
FOR JSON PATH, ROOT('pet owners')
)
PRINT @Result
这将打印以下JSON:
{
"pet owners":
[
{"person":{"id":2,"name":"Jack","pet":{"id":4,"name":"Bug"}}},
{"person":{"id":2,"name":"Jack","pet":{"id":5,"name":"Feature"}}},
{"person":{"id":3,"name":"Jill","pet":{"id":6,"name":"Fiend"}}}
]
}
但是,我想将宠物数据作为所有者数据中的数组:
{
"pet owners":
[
{
"person":
{
"id":2,"name":"Jack","pet":
[
{"id":4,"name":"Bug"},
{"id":5,"name":"Feature"}
]
}
},
{
"person":
{
"id":3,"name":"Jill","pet":
{"id":6,"name":"Fiend"}
}
}
]
}
我该怎么做?
答案 0 :(得分:9)
您可以使用以下查询:
SELECT pr.person_id AS [person.id], pr.person_name AS [person.name],
(
SELECT pt.pet_id AS id, pt.pet_name AS name
FROM @Pets pt WHERE pt.pet_owner=pr.person_id
FOR JSON PATH
) AS [person.pet]
FROM @Persons pr
FOR JSON PATH, ROOT('pet owners')
答案 1 :(得分:0)
使用深度嵌套的数组,子查询很快就无法处理:
d = {1: 2,
2:3,
3: 4,
5:6,
6:7}
我创建了一个关系(非json)视图,该视图连接了我的所有表,并在列别名中嵌入了json结构,就像 for json path 一样。但是我也有[]表示json节点是一个数组。像这样:
d= { 1: 4 , 2 :4 , 3:4 , 5:7 , 6:7}
我编写了一个存储过程,该过程在非json视图中创建一个json视图,该视图解析关系视图的列名并使json变得漂亮。见下文。用您的关系视图的名称调用它,它会创建一个视图。尚未经过全面测试,但对我有用。唯一需要说明的是,表需要具有称为 id的 id 列。它使用 string_agg()和 json_array() sql版本需要非常新。它还设置为在根目录中返回一个数组。需要调整以返回对象。
select id,foo, (select id, bar, (select ... for json path) things,
(select...) more_things) yet_more, select(...) blarg
答案 2 :(得分:0)
我按照@Razvan Socol 制作了以下 json 格式。
JSON
[
"domain_nm": "transactions",
"tables": [
{
"tableName": "transactions_details",
cols: [
{
"col_nm": "audit_transactions_details_guid",
"col_data_typ": "string"
}
]
}
]
]
SQL
select outer1.DOMAIN_NM as domain_nm,
(select inner2.TBL_NM as tableName,
(select inner1.COL_NM as col_nm, inner1.COL_DATA_TYP as col_data_typ
from ONBD_MTDT.CDM_TBL inner1
where inner1.TBL_NM=inner2.TBL_NM
FOR JSON PATH ) as cols
from ONBD_MTDT.CDM_TBL inner2
where inner2.DOMAIN_NM=outer1.DOMAIN_NM
group by inner2.DOMAIN_NM,inner2.TBL_NM
FOR JSON PATH ) as tables
from ONBD_MTDT.CDM_TBL outer1
group by outer1.DOMAIN_NM
FOR JSON PATH