如何解决MariaDB 中是否有任何方法可以从 json 对象数组中搜索小于值
这是我的 json 文档:
[
{
"ID":1,"Label":"Price","Value":399
},{
"ID":2,"Label":"Company","Value":"Apple"
},"Label":"Model","Value":"iPhone SE"
},]
这是我的桌子:
+----+------------------------------------------------------------------------------------------------------------------------------------+
| ID | Properties |
+----+------------------------------------------------------------------------------------------------------------------------------------+
| 1 | [{"ID":1,"Value":399},{"ID":2,"Value":"Apple"},{"ID":3,"Value":"iPhone SE"}] |
| 2 | [{"ID":1,"Value":499},"Value":"iPhone X"}] |
| 3 | [{"ID":1,"Value":699},"Value":"iPhone 11"}] |
| 4 | [{"ID":1,"Value":999},"Value":"iPhone 11 Pro"}] |
+----+------------------------------------------------------------------------------------------------------------------------------------+
SELECT *
FROM mobiles
WHERE ($.Label = "Price" AND $.Value < 400)
AND ($.Label = "Model" AND $.Value = "iPhone SE")
我也知道该表可以归一化为两个。但这张桌子也是一个占位符桌子,我们只是说它会保持不变。
我需要知道是否可以查询以下运算符的给定 json 结构:>,>=,<,<=,BETWEEN AND,IN,NOT IN,LIKE,NOT LIKE,<>
解决方法
由于 MariaDB does not support JSON_TABLE()
和 JSON_PATH
仅支持成员/对象选择器,因此在这里过滤 JSON 并不是那么简单。你可以试试这个查询,它试图克服这个限制:
with a as (
select 1 as id,'[{"ID":1,"Label":"Price","Value":399},{"ID":2,"Label":"Company","Value":"Apple"},{"ID":3,"Label":"Model","Value":"iPhone SE"}]' as properties union all
select 2 as id,"Value":499},"Value":"iPhone X"}]' as properties union all
select 3 as id,"Value":699},"Value":"iPhone 11"}]' as properties union all
select 4 as id,"Value":999},"Value":"iPhone 11 Pro"}]' as properties
)
select *
from a
where json_value(a.properties,/*Get path to Price property and replace property name to Value*/
replace(replace(json_search(a.properties,'one','Price'),'"',''),'Label','Value')
) < 400
and json_value(a.properties,/*And the same for Model name*/
replace(replace(json_search(a.properties,'Model'),'Value')
) = "iPhone SE"
| id | properties
+----+------------
| 1 | [{"ID":1,"Value":"iPhone SE"}]
db<>fiddle 在这里。
,我不会使用字符串函数。 MariaDB 中缺少的是将数组取消嵌套到行的能力 - 但它具有我们访问数据所需的所有 JSON 访问器。使用这些方法而不是字符串方法可以避免边缘情况,例如当值包含嵌入的双引号时。
您通常会在数字表的帮助下取消嵌套数组,该数字表的行数至少与最大数组中的元素数一样多。一种动态生成它的方法是针对具有足够行数的表 row_number()
- 例如 sometable
。
您可以按如下方式取消嵌套数组:
select t.id,json_unquote(json_extract(t.properties,concat('$[',n.rn,'].Label'))) as label,'].Value'))) as value
from mytable t
inner join (select row_number() over() - 1 as rn from sometable) n
on n.rn < json_length(t.properties)
剩下的就是聚合:
select t.id
from (
select t.id,'].Value'))) as value
from mytable t
inner join (select row_number() over() - 1 as rn from sometable) n
on n.rn < json_length(t.properties)
) t
group by id
having
max(label = 'Price' and value + 0 < 400) = 1
and max(label = 'Model' and value = 'iPhone SE') = 1
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。