Подивіться, чи містить масив JSON в MySQL об’єкт, ключ якого містить конкретну дату


18

Я намагаюся з'ясувати, чи є рядок, який містить конкретну дату в масиві JSON

Скажімо, мої дані виглядають так:

Настільні програми:

id | application_id | data
# Rows
1 | 1 | [{"data" : ["some", "data#1"], "date": "2016-04-21"}, {"data" : ["other", "data#1"], "date" : "2016-04-22"}]
2 | 2 | [{"data" : ["some", "data#2"], "date": "2016-04-21"}, {"data" : ["other", "data#2"], "date" : "2016-04-26"}]
3 | 1 | [{"data" : ["some", "data#3"], "date": "2016-04-22"}, {"data" : ["other", "data#3"], "date" : "2016-04-26"}]
4 | 3 | [{"data" : ["some", "data#4"], "date": "2016-04-26"}]

Як я можу знайти всі програми, дані яких містять дату '2016-04-26'?

Тому я в основному можу це зробити:

select id, json_extract(`data`, "$[*].date") from applications

Що повертає:

1 | ["2016-04-21", "2016-04-22"]
2 | ["2016-04-21", "2016-04-26"]
3 | ["2016-04-22", "2016-04-26"]
4 | ["2016-04-26"]

Але якщо спробувати використовувати json_extractв WHEREпункті, я можу використовувати його лише в тому випадку, якщо явно скажу ключ масиву в json_extractаргументі шляху, наприклад:

select * from applications where json_extract(`data`, "$[0].date") = "2016-04-26"

який правильно повертає рядок з id 4.

Але якщо я спробую використати підстановку на шляху, то це більше не працює:

select * from applications where json_extract(`data`, "$[*].date") = "2016-04-26"

це повинно повернути рядки 2, 3, 4.

Я спробував багато інших варіантів / варіацій, але не можу знайти спосіб структурування запиту правильно.

Чи щось подібне можливо навіть із поточною реалізацією MySQL JSON?

Відповіді:


15

Одне рішення, яке надає Морган Такер - @morgo, це використовувати json_containsтак:

select * from applications where json_contains(`data`, '{"date" : "2016-04-26"}')

На даний момент відповідь в порядку, але я вважаю, що це може мати певні проблеми з продуктивністю, і мені здається трохи хакітним (див. Наступний запит) - але я буду мати справу з тими, коли я потраплю :)

Якщо мені потрібно запитувати в діапазоні дат (від 2016-04-24до 2016-04-26), мені потрібно буде додати індивідуальну інформацію json_containsна кожен день у проміжок часу, як:

select * from applications where json_contains(`data`, '{"date" : "2016-04-26"}') or json_contains(`data`, '{"date" : "2016-04-25"}') or json_contains(`data`, '{"date" : "2016-04-24"}')

І це поверне недійсні дані, якби я мав dateключ, вкладений деінде

Тож якщо у вас інше рішення, я хотів би знати


як варіант - визначте максимальну глибину масиву дат - SELECT MAX (json_depth (дані - >> '$ [*]. дата')), ніж через цикл у витягуванні збереженої процедури для тимчасових таблиць - id та вибрана дата - виберіть ідентифікатор, json_extract ( data, "$ [0] .date") як "дата" в додатках, ніж - виберіть ідентифікатор, json_extract ( data, "$ [1] .date") як "дата" для програм та ін., ніж застосувати весь фільтр і у вас є список id
a_vlad

ти дав мені підказку, як використовувати синтаксис json_contains
Джиммі Іленлоа
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.