SQL查询以确定JSON值是否包含指定的属性

时间:2016-09-27 18:32:58

标签: mysql json attributes

我有一个包含列的表,用于存储每行的JSON值。目前,这些都没有标准化。我想最终将每个JSON值标准化为数量和属性标题。是否有可用于确定每个JSON值是否包含指定属性的查询?

作为示例,以下是一些JSON值的样子:

{"name":"Item 1","cost":"4.99"}
{"name":"Item 2"}
{"name":"Item 3","cost":""}
{"name":"Item 4"}

我如何:

  • 确定哪些行 a"成本"属性(第1项和第3项)
  • 确定哪些行没有"成本"属性(项目2和4)
  • 确定哪些行具有为"成本"设置的值。属性(第1项)

谢谢!这是我第一次询问(至少最近),所以任何帮助都非常感谢!

5 个答案:

答案 0 :(得分:9)

我假设您正在使用MySQL 5.7,它添加了JSON数据类型。使用JSON_EXTRACT(colname, '$.cost')访问cost媒体资源。这将是NULL没有这样的财产。

  1. WHERE JSON_EXTRACT(colname, '$.cost') IS NOT NULL
  2. WHERE JSON_EXTRACT(colname, '$.cost') IS NULL
  3. WHERE JSON_EXTRACT(colname, '$.cost') != ''
  4. 如果JSON中的值为NULL,它也将为null;我认为没有办法将其与不存在的价值区分开来。

答案 1 :(得分:0)

实际上,您可以通过将JSON_EXTRACT结果与其自身进行比较来做到这一点:

JSON_EXTRACT(colname,'$。“ cost”')= JSON_EXTRACT(colname,'$。“ cost”')

如果您的JSON列中没有相应的密钥,则它将以某种方式为“ false” / null。

通过这种方式,您可以找到具有要搜索的键的所有条目。如果您希望所有不具有键的条目,那么您就不能使用NOT运算符。您必须这样做:

SELECT * FROM表名的ID不在(SELECT ID从表名的ID不在)JSON_EXTRACT(colname,'$。“ cost”')= JSON_EXTRACT(colname,'$。“ cost”'))

我知道它看起来像伏都教徒,但似乎可行。

答案 2 :(得分:0)

如果仅需要检查json密钥是否存在,则可以使用JSON_CONTAINS_PATH。我希望它比JSON_EXTRACT更快。

mySQL 8.0 docs

示例:

我在数据库中有一个权限列。结构如下:

{
    "users": {
        "user1" : "rw",
        "user2" : "r"
    },
    "groups": {
        "root": "rw",
        "anotherGroup" : "r"
    }
}

如果我要获取所有具有根组的项目(关于实际权限),请使用以下方法:

SELECT * FROM `filesystem_folders` where JSON_CONTAINS_PATH(permissions, 'one', '$.groups.root');

我在上面的 select 之间做了一个非常简单的时间比较,花费了 12.90s (10000次读取)。使用 JSON_EXTRACT

选择以下内容
 SELECT * FROM `filesystem_folders` where JSON_EXTRACT(permissions, '$.groups.root') IS NOT NULL;

花了 15.13s 。因此,相差很小。

答案 3 :(得分:-1)

MySQL没有解析JSON数组。它像对待它们一样对待它们。因此,您必须使用LIKE

答案 4 :(得分:-1)

如果您使用的是不带JSON函数的MySQL(5.7版之前的版本),或者想检查列表中或嵌套嵌套的JSON中是否有任何标签。

以下是使用LIKE的示例:

SELECT case when colname like '%cost%' then 1 else 0 end as has_cost,
       case when colname like '%cost":""%' then 1 else 0 end as has_cost_with_no_value
FROM tablename