A_V*_*A_V 5 sql-server json sql-server-2019
我想使用聚合来构建一个简单的单维标量值 JSON 数组,如下面示例中的 LuckyNumbers 数组:
[{
"id": 1,
"name": "Josian",
"LuckyNumbers": [581, 777]
}, {
"id": 2,
"name": "Paul",
"LuckyNumbers": [123551, 5, 646464, 1345, 75, 76]
}, {
"id": 3,
"name": "Seasonique",
"LuckyNumbers": [1]
}]
Run Code Online (Sandbox Code Playgroud)
使用 Postgresql 12,您可以使用本机聚合函数(fiddle)来完成此操作
--Postgresql 12 schema
create table person ( Id int primary key, name varchar(20) );
insert into person values (1,'Josian'), (2,'Paul'), (3,'Seasonique');
create table LuckyNumbers (PersonId int references person(Id), LuckyNumber int);
insert into LuckyNumbers (PersonId, LuckyNumber) values (1,581), (1,777), (2,123551), (2,5), (2,646464), (2,1345), (2,75), (2,76), (3,1);
--Query to JSON
select
array_to_json(array_agg(row_to_json(r))) "PersonsNumbers"
from (
select
p.id,p.name,json_agg(ln.LuckyNumber) "LuckyNumbers"
from person as p
inner join
LuckyNumbers as ln
on
p.id=ln.PersonId
group by p.id,p.name
)
r
Run Code Online (Sandbox Code Playgroud)
这将输出所需的结果,与上面完全相同。
然而,下面的 SqlServer2019 示例需要使用 string_agg (一个字符串函数),然后手动连接数组括号。(小提琴)
--Sqlserver 2019 schema creation
create table person ( Id int primary key, name nvarchar(20) );
insert person values (1,'Josian'), (2,'Paul'), (3,'Seasonique');
create table LuckyNumbers (PersonId int foreign key references person(Id), LuckyNumber int);
insert LuckyNumbers (PersonId, LuckyNumber) values (1,581), (1,777), (2,123551), (2,5), (2,646464), (2,1345), (2,75), (2,76), (3,1);
--Query to JSON
SELECT p.id
,p.NAME
,Json_Query('[' + string_agg(ln.LuckyNumber, ',') + ']') 'LuckyNumbers'
FROM person p
INNER JOIN LuckyNumbers ln ON p.id = ln.PersonId
GROUP BY p.id
,p.NAME
FOR json path
--JSON to Query : OPENJSON and out apply allow you to read back the array !
DECLARE @JsonOutput NVARCHAR(max) = (
SELECT p.id
,p.NAME
,Json_Query('[' + string_agg(ln.LuckyNumber, ',') + ']') 'LuckyNumbers'
FROM person p
INNER JOIN LuckyNumbers ln ON p.id = ln.PersonId
GROUP BY p.id
,p.NAME
FOR json path
);
SELECT id
,NAME
,luckynumber
FROM openjson(@JsonOutput) WITH (
id INT 'strict $.id'
,NAME NVARCHAR(50) '$.name'
,LuckyNumbers NVARCHAR(MAX) '$.LuckyNumbers' AS JSON
)
OUTER APPLY OPENJSON(LuckyNumbers) WITH (LuckyNumber NVARCHAR(8) '$');
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来使用 Sqlserver 来做到这一点?我是否错过了类似于 Postgre 的本机聚合函数json_agg?
您可以像这样近似所需的输出:
SELECT p.id
, p.[name]
, LuckNumbers = (
SELECT ln.LuckyNumber
FROM #LuckyNumbers ln
WHERE ln.PersonId = p.Id
FOR JSON PATH
)
FROM #person p
FOR JSON PATH;
Run Code Online (Sandbox Code Playgroud)
本质上,为每个人的幸运数字创建一个 JSONint值数组。我不知道如何从每个值中删除“LuckyNumber”标签;这是我第一次在 SQL Server 上使用 JSON。
输出看起来像:
[
{
“id”:1
,"name":"乔斯安"
,“幸运数字”:[
{“幸运号码”:581}
,{"幸运数字":777}
]
}
,{
“id”:2
,"name":"保罗"
,“幸运数字”:[
{“幸运号码”:123551}
,{"幸运数字":5}
,{"幸运号码":646464}
,{"幸运号码":1345}
,{"幸运数字":75}
,{"幸运数字":76}
]
}
,{
“id”:3
,"name":"季节"
,“幸运数字”:[
{“幸运数字”:1}
]
}
]
| 归档时间: |
|
| 查看次数: |
7589 次 |
| 最近记录: |