在 SQL 服务器中构建和分组 JSON 对象
Building and Grouping JSON Object in SQL Server
我有以下 table,我正在尝试将这些行组合成 JSON 个对象。
Username
AccessKeys
Marker
user1
{"Account":"1","Checking":"0001","Loan":"null","Savings":0}
New
user2
{"Account":"2","Checking":"0001","Loan":"null","Savings":0}
New
user2
{"Account":"3","Checking":"0001","Loan":"null","Savings":0}
New
结果应该是这样的。
Username
JSON
user1
{"Accounts": [{"Account": "1","Checking": "0001","Loan": null,"Savings": 0}],"Marker": "New"}
user2
{"Accounts": [{"Account": "1","Checking": "0001","Loan": null,"Savings": 0},{"Account": "2","Checking": "0001","Loan": null,"Savings": 0}],"Marker": "New"}
我当前的查询是这样的。我已经能够做到这一点,但不确定如何从这里开始。
SELECT
Username
,Accounts = (
SELECT
Account
,Checking
,Loan
,Savings
FROM dbo.Accounts A1
WHERE A1.Account= A2.Account
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
)
FROM
dbo.Accounts A2
GROUP BY
Accounts
,Username
;
提前致谢!
解决方案
这是我的最终查询。
SELECT
Username
,(
SELECT
Accounts = JSON_QUERY((
SELECT AK.*
FROM
dbo.Accounts A2
CROSS APPLY OPENJSON(Accounts) WITH (
Account nvarchar(10)
,Checking nvarchar(10)
,Loan nvarchar(10)
,Savings int
) AK
WHERE A2.Username = A1.Username
FOR JSON PATH
))
,'New' Marker
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) JSON
FROM dbo.Accounts A1
GROUP BY Username
;
使用SQL服务器创建JSON数组元素通常涉及json_query,例如...
select
Username,
[JSON] = (
select
[Accounts] = json_query((
select AK.*
from dbo.Accounts A2
cross apply openjson(AccessKeys) with (
Account nvarchar(10),
Checking nvarchar(10),
Loan nvarchar(10),
Savings int
) AK
where A2.Username = A1.Username
for json path
)),
[Marker]
for json path, without_array_wrapper
)
from dbo.Accounts A1
group by Username, Marker;
产生结果...
Username
JSON
user1
{"Accounts":[{"Account":"1","Checking":"0001","Loan":"null","Savings":0}],"Marker":"New"}
user2
{"Accounts":[{"Account":"2","Checking":"0001","Loan":"null","Savings":0},{"Account":"3","Checking":"0001","Loan":"null","Savings":0}],"Marker":"New"}
您可以使用 ROOT
添加根 属性, 并删除 WITHOUT_ARRAY_WRAPPER
因为您实际上需要此处的数组。
SELECT
Username
,JSON = (
SELECT
Account
,Checking
,Loan
,Savings
FROM dbo.Accounts A1
WHERE A1.Username = A2.Username
FOR JSON PATH, ROOT('Accounts')
)
FROM
dbo.Accounts A2
GROUP BY
A2.Username;
这确实有重新查询 table 的缺点。为了提高性能,您可以使用 STRING_AGG
手动构造 JSON(不幸的是,SQL 服务器没有 JSON_AGG
)。
SELECT
Username
,JSON = (
SELECT Accounts = JSON_QUERY('[' + STRING_AGG(
(SELECT
A.Account
,A.Checking
,A.Loan
,A.Savings
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
), ',') + ']')
FOR JSON PATH)
FROM
dbo.Accounts A
GROUP BY
A.Username;
我有以下 table,我正在尝试将这些行组合成 JSON 个对象。
Username | AccessKeys | Marker |
---|---|---|
user1 | {"Account":"1","Checking":"0001","Loan":"null","Savings":0} |
New |
user2 | {"Account":"2","Checking":"0001","Loan":"null","Savings":0} |
New |
user2 | {"Account":"3","Checking":"0001","Loan":"null","Savings":0} |
New |
结果应该是这样的。
Username | JSON |
---|---|
user1 | {"Accounts": [{"Account": "1","Checking": "0001","Loan": null,"Savings": 0}],"Marker": "New"} |
user2 | {"Accounts": [{"Account": "1","Checking": "0001","Loan": null,"Savings": 0},{"Account": "2","Checking": "0001","Loan": null,"Savings": 0}],"Marker": "New"} |
我当前的查询是这样的。我已经能够做到这一点,但不确定如何从这里开始。
SELECT
Username
,Accounts = (
SELECT
Account
,Checking
,Loan
,Savings
FROM dbo.Accounts A1
WHERE A1.Account= A2.Account
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
)
FROM
dbo.Accounts A2
GROUP BY
Accounts
,Username
;
提前致谢!
解决方案
这是我的最终查询。
SELECT
Username
,(
SELECT
Accounts = JSON_QUERY((
SELECT AK.*
FROM
dbo.Accounts A2
CROSS APPLY OPENJSON(Accounts) WITH (
Account nvarchar(10)
,Checking nvarchar(10)
,Loan nvarchar(10)
,Savings int
) AK
WHERE A2.Username = A1.Username
FOR JSON PATH
))
,'New' Marker
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) JSON
FROM dbo.Accounts A1
GROUP BY Username
;
使用SQL服务器创建JSON数组元素通常涉及json_query,例如...
select
Username,
[JSON] = (
select
[Accounts] = json_query((
select AK.*
from dbo.Accounts A2
cross apply openjson(AccessKeys) with (
Account nvarchar(10),
Checking nvarchar(10),
Loan nvarchar(10),
Savings int
) AK
where A2.Username = A1.Username
for json path
)),
[Marker]
for json path, without_array_wrapper
)
from dbo.Accounts A1
group by Username, Marker;
产生结果...
Username | JSON |
---|---|
user1 | {"Accounts":[{"Account":"1","Checking":"0001","Loan":"null","Savings":0}],"Marker":"New"} |
user2 | {"Accounts":[{"Account":"2","Checking":"0001","Loan":"null","Savings":0},{"Account":"3","Checking":"0001","Loan":"null","Savings":0}],"Marker":"New"} |
您可以使用 ROOT
添加根 属性, 并删除 WITHOUT_ARRAY_WRAPPER
因为您实际上需要此处的数组。
SELECT
Username
,JSON = (
SELECT
Account
,Checking
,Loan
,Savings
FROM dbo.Accounts A1
WHERE A1.Username = A2.Username
FOR JSON PATH, ROOT('Accounts')
)
FROM
dbo.Accounts A2
GROUP BY
A2.Username;
这确实有重新查询 table 的缺点。为了提高性能,您可以使用 STRING_AGG
手动构造 JSON(不幸的是,SQL 服务器没有 JSON_AGG
)。
SELECT
Username
,JSON = (
SELECT Accounts = JSON_QUERY('[' + STRING_AGG(
(SELECT
A.Account
,A.Checking
,A.Loan
,A.Savings
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
), ',') + ']')
FOR JSON PATH)
FROM
dbo.Accounts A
GROUP BY
A.Username;