Как отфильтровать объект Json в массиве Json? - PullRequest
3 голосов
/ 02 мая 2019

У меня есть некоторые данные, хранящиеся в столбце sql, который выглядит как

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

Теперь я хочу создать предложение where, которое бы находило все "элементы", у которых значение "fromCompanyId" равно "4".

Все, что я нашел до сих пор, это

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 голосов
/ 03 мая 2019

SQL не является подходящим местом для этого поиска.Помимо того, насколько плохой будет производительность этого поиска, запрос будет очень дорогим для ресурсов БД, таких как CPU и IO.запрос будет экспоненциально медленным по мере роста данных в таблице.даже без большого прироста данных, если фактический JSON больше 8000char (4k, если хранится как NVARCHAR), он будет храниться вне строки, следовательно, каждый раз, когда ему нужно читать BLOB.

, скорее, я бы рекомендовалпросто читайте из db и анализируйте inn на стороне приложения на любом языкеэто было бы дешевле.

короче говоря: это не задача SQL.Вы должны посмотреть на рабочий процесс и процесс улучшения в первую очередь.если поисковый запрос является обычным рабочим процессом пользователя, то сама разработка схемы может оказаться неподходящей для этого рабочего процесса.

0 голосов
/ 02 мая 2019

Вам нужно 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
...