我正在尝试展平由FOR JSON
构造的对象数组。
我的查询如下:
select
(
select id from MyTable
where id in (select value from OPENJSON(@jsonArray))
FOR JSON PATH
) existing,
(
select value id from OPENJSON(@jsonArray)
where value not in (select Id from MyTable)
FOR JSON PATH
) missing
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
生成的JSON是:
{
"existing": [
{
"id": "a00cd8f6-d1c6-4604-b235-59d3cacd5bcc"
},
{
"id": "052455b6-6bf5-47d3-8bee-7ba98d7fbd50"
}
],
"missing": [
{
"id": "328add2d-e8f2-4a0e-af54-5b1733310170"
}
]
}
我想要的是:
{
"existing": [
{
"id": "a00cd8f6-d1c6-4604-b235-59d3cacd5bcc"
},
{
"id": "052455b6-6bf5-47d3-8bee-7ba98d7fbd50"
}
],
"missing": [
"328add2d-e8f2-4a0e-af54-5b1733310170"
]
}
缺少的数组不应包含json对象,而应包含值。 有什么建议吗?
答案 0 :(得分:1)
如果您使用的是SQL Server 2017,则可以使用JSON_QUERY
和STRING_AGG
构建数组(使用SQL Server 2016时,您不能使用STRING_AGG
,因此必须有点estra的工作,但以下想法仍然有效):
declare @missing table(id varchar(max))
declare @existing table(id varchar(max))
insert into @missing values ('a00cd8f6-d1c6-4604-b235-59d3cacd5bcc')
insert into @missing values ('052455b6-6bf5-47d3-8bee-7ba98d7fbd50')
insert into @existing values ('328add2d-e8f2-4a0e-af54-5b1733310170')
select
(
select id from @missing
FOR JSON PATH
) existing,
(
select JSON_QUERY(concat('[' , STRING_AGG(concat('"' , STRING_ESCAPE(id, 'json') , '"'),',') , ']'))
from @existing
) missing
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
结果:
{
"existing": [
{
"id": "a00cd8f6-d1c6-4604-b235-59d3cacd5bcc"
},
{
"id": "052455b6-6bf5-47d3-8bee-7ba98d7fbd50"
}
],
"missing": [
"328add2d-e8f2-4a0e-af54-5b1733310170"
]
}
答案 1 :(得分:0)
这并不像应该做的那么简单...
AFAIK无法使用sql-server创建裸 json数组。但是您可以在字符串级别上欺骗它:
SELECT SUM(meta_value) FROM `order_itemmeta` im2
WHERE meta_key = '_qty' AND
im2.order_item_id IN (
SELECT im.order_item_id
FROM `order_itemmeta` im
RIGHT JOIN `order_items` i ON im.order_item_id = i.order_item_id
WHERE im.meta_value = "' . $todays_date . '"
);
-这将创建所需的对象数组
DECLARE @exist TABLE(id VARCHAR(100));
DECLARE @miss TABLE(id VARCHAR(100));
INSERT INTO @exist VALUES ('exist1'),('exist2');
INSERT INTO @miss VALUES ('miss1'),('miss2');
-这将使用一些相当丑陋的技巧创建 naked 数组。
SELECT id FROM @exist
FOR JSON PATH
-现在我们必须将两者结合起来。再一次,我们需要一个技巧。我们在JSON文字上使用SELECT REPLACE(REPLACE(REPLACE(
(
SELECT id from @miss
FOR JSON PATH
),'"id":',''),'{',''),'}','')
以避免转义引号。
JSON_QUERY()
这就是结果
SELECT
(
SELECT id FROM @exist
FOR JSON PATH
) AS existing
,JSON_QUERY(
REPLACE(REPLACE(REPLACE(
(
SELECT id from @miss
FOR JSON PATH
),'"id":',''),'{',''),'}','')
) AS missing
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER;
我不知道为什么为什么不能做到这一点开箱即用 ...
答案 2 :(得分:0)
使用游标追加
DECLARE @missing nvarchar(max),
@json nvarchar(max) = (select
(
select id from MyTable
where id in (select value from OPENJSON(@jsonArray))
FOR JSON PATH
) existing
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)
DECLARE missing_cursor CURSOR FOR
select value id
from OPENJSON(@jsonArray)
where value not in (select Id from MyTable)
OPEN missing_cursor
FETCH NEXT FROM missing_cursor
INTO @missing
WHILE @@FETCH_STATUS = 0
BEGIN
SET @json = JSON_MODIFY(@json,'append $.missing', @missing)
FETCH NEXT FROM missing_cursor
INTO @missing
END
CLOSE missing_cursor;
DEALLOCATE missing_cursor;
select @json