查看MySQL中的JSON数组是否包含其键包含特定日期的对象


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_extractWHERE子句中使用,则仅当我在json_extract的path参数中明确告诉数组的键时才能使用它,例如:

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实现中,这样的事情甚至可能吗?

Answers:


15

Morgan Tucker-@morgo提供的一种解决方案是这样使用json_contains

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

目前,答案是可以的,但我相信它可能会遇到一些性能问题,并且让我感到有些hack跷(请参阅下一个查询)-但我到达那里时,我会处理这些问题:)

如果我需要查询一个日期范围(从2016-04-242016-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(data->>'$ [*]。date')),然后通过存储过程中的循环将其提取到临时表中-ID和选定的日期-选择ID,data从应用程序中将json_extract(,“ $ [0] .date”)作为'date',然后从应用程序中选择id,从应用程序中选择json_extract(data,“ $ [1] .date”)作为'date',等等。并有ID列表
a_vlad16年

您为我提供了有关如何使用json_contains语法的线索
Jimmy Ilenloa
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.