微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

MariaDB 中是否有任何方法可以从 json 对象数组中搜索小于值

如何解决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
    

Demo on DB Fiddle

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。