如何过滤Json数组中的Json对象?

时间:2019-05-02 19:01:30

标签: json sql-server sql-server-2017

我在sql列中存储了一些数据,看起来像

{
  "items": [
    { "ids": [4], "fromCompanyId": 4 },
    { "ids": [6, 1], "fromCompanyId": 1 }
  ]
}

现在,我想创建一个where子句,以查找所有具有“ 4”的“ fromCompanyId”的“项目”。

到目前为止,我发现的只是

WHERE JSON_VALUE(jsonInfo,'$.info.address[0].state') LIKE 'US%'

,但是它们正在对数组索引进行硬编码。我需要找到所有匹配项。

我也在尝试openJson,但仍然无法正常工作

where 4 in (select fromCompanyId  from openjson(Details, '$.items.fromCompanyId') WITH( [fromCompanyId] int '$.fromCompanyId')))

2 个答案:

答案 0 :(得分:0)

您需要在多个级别上openjson。像这样的东西。

declare @json nvarchar(max)=N'{
  "items": [
    { "ids": [4], "fromCompanyId": 4 },
    { "ids": [6, 1], "fromCompanyId": 1 }
  ]
}'

select id,fromCompanyId
from openjson(@json,'$.items') j --path to the main array
cross apply openjson(value,'$.ids') -- path inside element of main array
with(id int '$')
cross apply openjson(value)
with (
fromCompanyId int '$.fromCompanyId'
)
where fromCompanyId=4

类似于表字段。

declare @tbl table (id int, detail nvarchar(max))
insert @tbl (id,detail) values
(1,N'{
  "items": [
    { "ids": [4], "fromCompanyId": 4 },
    { "ids": [6, 1], "fromCompanyId": 1 }
  ]
}'),
(2,N'{
  "items": [
    { "ids": [5], "fromCompanyId": 4 },
    { "ids": [7,9], "fromCompanyId": 4 },
    { "ids": [6, 1], "fromCompanyId": 1 }
  ]
}')

select id,jid,fromCompanyId
from @tbl
cross apply openjson(detail,'$.items') -- path to the main array
cross apply openjson(value,'$.ids') -- path inside array element
with(jid int '$')
cross apply openjson(value)
with (
fromCompanyId int '$.fromCompanyId'
)
where fromCompanyId=4

答案 1 :(得分:0)

SQL不适用于此搜索。除了这种搜索的性能会很差之外,对于数据库资源(如CPU和IO),查询将非常昂贵。 随着表中数据的增长,查询将呈指数级增长。 如果实际JSON大于8000char(如果存储为NVARCHAR为4k),甚至没有太多数据增长,那么它将存储在行外,因此每次必须读取BLOB时。

相反,我建议您仅从db读取并解析inn应用程序端的任何语言。这样会更便宜。

简而言之

:这不是SQL任务。您应该首先查看工作流程和流程改进。如果搜索查询是常规用户工作流程,则自行设计架构可能不适用于此工作流程。