Xem liệu một mảng JSON trong MySQL có chứa một đối tượng có khóa giữ một ngày cụ thể không


17

Tôi đang cố gắng tìm hiểu xem có một hàng có chứa một ngày cụ thể trong một mảng JSON không

Giả sử dữ liệu của tôi trông như thế này:

Bảng ứng dụng:

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"}]

Làm cách nào tôi có thể tìm thấy tất cả các ứng dụng có dữ liệu chứa ngày '2016-04-26'?

Vì vậy, về cơ bản tôi có thể làm điều này:

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

Trả về:

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"]

Nhưng nếu cố gắng sử dụng json_extracttrong WHEREmệnh đề, tôi chỉ có thể sử dụng nó nếu tôi nói rõ ràng khóa của mảng trong json_extractđối số đường dẫn của, như vậy:

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

trả về đúng hàng với id 4.

Nhưng nếu tôi cố gắng sử dụng ký tự đại diện trong đường dẫn thì nó không còn hoạt động:

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

điều này sẽ trả về các hàng 2, 3, 4.

Tôi đã thử nhiều tùy chọn / biến thể khác nhưng dường như tôi không thể tìm ra cách cấu trúc truy vấn chính xác.

Là một cái gì đó như thế này thậm chí có thể với việc triển khai MySQL JSON hiện tại?

Câu trả lời:


14

Một giải pháp được cung cấp bởi Morgan Tucker - @morgo là sử dụng json_containsnhư vậy:

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

Bây giờ câu trả lời là OK, nhưng tôi tin rằng nó có thể có một số vấn đề về hiệu suất và cảm thấy hơi khó chịu với tôi (xem truy vấn tiếp theo) - nhưng tôi sẽ giải quyết những vấn đề đó khi tôi đến đó :)

Nếu tôi cần truy vấn trên phạm vi ngày (từ 2016-04-24đến 2016-04-26), tôi sẽ cần thêm một tùy json_containschọn cho mỗi ngày trong khoảng thời gian như vậy:

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"}')

Và điều này sẽ trả về dữ liệu không hợp lệ nếu tôi có một datekhóa được lồng ở một nơi khác

Vì vậy, nếu bạn có một giải pháp khác, tôi muốn biết


dưới dạng biến thể - xác định độ sâu tối đa của mảng ngày - CHỌN MAX (json_depth (dữ liệu - >> '$ [*]. date')), hơn thông qua vòng lặp trong trích xuất thủ tục được lưu trữ vào bảng tạm thời - id và ngày được chọn - chọn id, json_extract ( data, "$ [0] .date") là 'ngày' từ các ứng dụng, hơn- chọn id, json_extract ( data, "$ [1] .date") dưới dạng 'ngày' từ các ứng dụng, v.v. và có danh sách id
a_vlad

bạn đã cho tôi manh mối về cách sử dụng cú pháp json_contains
Jimmy Ilenloa
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.