Azure SQL:以列为键生成 JSON
Azure SQL: generate JSON with column as key
我的 sql 服务器 table
中有以下数据
Name
Value
ValueHash
country
aaa
zzz
lastname
ccc
yyy
email
a@a.com
xxx
firstName
bbb
www
我想要下面的 Json 使用 sql 查询
{
"lastname": {
"value": "ccc",
"valueHash": "yyy"
},
"email": {
"value": "a@a.com",
"valueHash": "xxx"
},
"firstName": {
"value": "bbb",
"valueHash": "www"
},
"country": {
"value": "aaa",
"valueHash": "zzz"
}
}
我可以提出以下查询
select Value as 'value', ValueHash as 'valueHash' from user
where id=752594
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
哪个returns
{
"value": "ccc",
"valueHash": "yyy"
},
{
"value": "a@a.com",
"valueHash": "xxx"
},
{
"value": "bbb/T1B+4nzpVhb0M",
"valueHash": "www"
},
{
"value": "aaa",
"valueHash": "zzz"
}
尝试了 generate json with column value as json dict key 的解决方案,但遇到编译器错误。
有人可以帮我解决这个问题吗? TIA
这会产生类似的结果。告诉 SQL 服务器不要对内部值使用数组包装器会导致它转义结果:
WITH YourTable AS(
SELECT *
FROM (VALUES('country','aaa','zzz'),
('lastname','ccc','yyy'),
('email','a@a.com','xxx'),
('firstName','bbb','www'))V(Name,Value,ValueHash))
SELECT (SELECT value,
ValueHash
WHERE YT.Name = 'lastname'
FOR JSON PATH) AS lastname,
(SELECT value,
ValueHash
WHERE YT.Name = 'email'
FOR JSON PATH) AS email,
(SELECT value,
ValueHash
WHERE YT.Name = 'firstName'
FOR JSON PATH) AS firstName,
(SELECT value,
ValueHash
WHERE YT.Name = 'country'
FOR JSON PATH) AS country
FROM YourTable YT
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER;
很遗憾,SQL服务器没有JSON_AGG
或JSON_OBJECT_AGG
。所以你需要用 STRING_AGG
和 STRING_ESCAPE
来破解它
SELECT
'{' +
STRING_AGG(
CONCAT(
'"',
STRING_ESCAPE(u.Name, 'json'),
'":',
v.json
), ','
) + '}'
FROM [user] u
CROSS APPLY (
SELECT
u.Value AS value,
u.ValueHash AS valueHash
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) v(json)
WHERE u.id = 752594;
如果您曾经想要 return 多个对象,假设您在 table 中有一列 id
,正如您在 WHERE
中暗示的那样条款,你可以这样做:
DECLARE @t TABLE (id INT,
Name VARCHAR(100),
Value VARCHAR(100),
ValueHash VARCHAR(100));
INSERT @t (id, Name, Value, ValueHash)
VALUES (1, 'country', 'aaa', 'zzz'),
(1, 'lastname', 'ccc', 'yyy'),
(1, 'email', 'a@a.com', 'xxx'),
(1, 'firstName', 'bbb', 'www'),
(2, 'country', 'aaa2', 'zzz2'),
(2, 'lastname', 'ccc2', 'yyy2'),
(2, 'email', 'a2@a2.com', 'xxx2'),
(2, 'firstName', 'bbb2', 'www2');
SELECT (SELECT Value, ValueHash
FROM @t
WHERE id = t1.id AND Name = 'lastname'
FOR JSON AUTO, WITHOUT_ARRAY_WRAPPER) lastname,
(SELECT Value, ValueHash
FROM @t
WHERE id = t1.id AND Name = 'email'
FOR JSON AUTO, WITHOUT_ARRAY_WRAPPER) email,
(SELECT Value, ValueHash
FROM @t
WHERE id = t1.id AND Name = 'firstName'
FOR JSON AUTO, WITHOUT_ARRAY_WRAPPER) firstName,
(SELECT Value, ValueHash
FROM @t
WHERE id = t1.id AND Name = 'country'
FOR JSON AUTO, WITHOUT_ARRAY_WRAPPER) country
FROM @t t1
WHERE t1.Name = 'lastname'
FOR JSON PATH;
请注意,与 Larnu 的解决方案一样,它也会转义 Value
和 ValueHash
的值。
我的 sql 服务器 table
中有以下数据Name | Value | ValueHash |
---|---|---|
country | aaa | zzz |
lastname | ccc | yyy |
a@a.com | xxx | |
firstName | bbb | www |
我想要下面的 Json 使用 sql 查询
{
"lastname": {
"value": "ccc",
"valueHash": "yyy"
},
"email": {
"value": "a@a.com",
"valueHash": "xxx"
},
"firstName": {
"value": "bbb",
"valueHash": "www"
},
"country": {
"value": "aaa",
"valueHash": "zzz"
}
}
我可以提出以下查询
select Value as 'value', ValueHash as 'valueHash' from user
where id=752594
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
哪个returns
{
"value": "ccc",
"valueHash": "yyy"
},
{
"value": "a@a.com",
"valueHash": "xxx"
},
{
"value": "bbb/T1B+4nzpVhb0M",
"valueHash": "www"
},
{
"value": "aaa",
"valueHash": "zzz"
}
尝试了 generate json with column value as json dict key 的解决方案,但遇到编译器错误。
有人可以帮我解决这个问题吗? TIA
这会产生类似的结果。告诉 SQL 服务器不要对内部值使用数组包装器会导致它转义结果:
WITH YourTable AS(
SELECT *
FROM (VALUES('country','aaa','zzz'),
('lastname','ccc','yyy'),
('email','a@a.com','xxx'),
('firstName','bbb','www'))V(Name,Value,ValueHash))
SELECT (SELECT value,
ValueHash
WHERE YT.Name = 'lastname'
FOR JSON PATH) AS lastname,
(SELECT value,
ValueHash
WHERE YT.Name = 'email'
FOR JSON PATH) AS email,
(SELECT value,
ValueHash
WHERE YT.Name = 'firstName'
FOR JSON PATH) AS firstName,
(SELECT value,
ValueHash
WHERE YT.Name = 'country'
FOR JSON PATH) AS country
FROM YourTable YT
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER;
很遗憾,SQL服务器没有JSON_AGG
或JSON_OBJECT_AGG
。所以你需要用 STRING_AGG
和 STRING_ESCAPE
SELECT
'{' +
STRING_AGG(
CONCAT(
'"',
STRING_ESCAPE(u.Name, 'json'),
'":',
v.json
), ','
) + '}'
FROM [user] u
CROSS APPLY (
SELECT
u.Value AS value,
u.ValueHash AS valueHash
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) v(json)
WHERE u.id = 752594;
如果您曾经想要 return 多个对象,假设您在 table 中有一列 id
,正如您在 WHERE
中暗示的那样条款,你可以这样做:
DECLARE @t TABLE (id INT,
Name VARCHAR(100),
Value VARCHAR(100),
ValueHash VARCHAR(100));
INSERT @t (id, Name, Value, ValueHash)
VALUES (1, 'country', 'aaa', 'zzz'),
(1, 'lastname', 'ccc', 'yyy'),
(1, 'email', 'a@a.com', 'xxx'),
(1, 'firstName', 'bbb', 'www'),
(2, 'country', 'aaa2', 'zzz2'),
(2, 'lastname', 'ccc2', 'yyy2'),
(2, 'email', 'a2@a2.com', 'xxx2'),
(2, 'firstName', 'bbb2', 'www2');
SELECT (SELECT Value, ValueHash
FROM @t
WHERE id = t1.id AND Name = 'lastname'
FOR JSON AUTO, WITHOUT_ARRAY_WRAPPER) lastname,
(SELECT Value, ValueHash
FROM @t
WHERE id = t1.id AND Name = 'email'
FOR JSON AUTO, WITHOUT_ARRAY_WRAPPER) email,
(SELECT Value, ValueHash
FROM @t
WHERE id = t1.id AND Name = 'firstName'
FOR JSON AUTO, WITHOUT_ARRAY_WRAPPER) firstName,
(SELECT Value, ValueHash
FROM @t
WHERE id = t1.id AND Name = 'country'
FOR JSON AUTO, WITHOUT_ARRAY_WRAPPER) country
FROM @t t1
WHERE t1.Name = 'lastname'
FOR JSON PATH;
请注意,与 Larnu 的解决方案一样,它也会转义 Value
和 ValueHash
的值。