【问题标题】:Retrieve property values from json array filtered on another property value从另一个属性值过滤的 json 数组中检索属性值
【发布时间】:2020-10-27 03:38:29
【问题描述】:

我有一个包含 json 数组的列 (column_metadata) 的表

[{
    "ORDER": -1,
    "READONLY": false,
    "COLUMNNAME": "id",
    "COLUMNTYPE": "int",
    "FILTERABLE": false,
    "SUMMARYVIEW": false,
    "WHITELISTED": false
  },
  {
    "ORDER": -1,
    "READONLY": true,
    "COLUMNNAME": "name",
    "COLUMNTYPE": "varchar",
    "FILTERABLE": true,
    "SUMMARYVIEW": true,
    "WHITELISTED": true
  },
  {
    "ORDER": -1,
    "READONLY": false,
    "COLUMNNAME": "description",
    "COLUMNTYPE": "varchar",
    "FILTERABLE": true,
    "SUMMARYVIEW": true,
    "WHITELISTED": true
  }]

我正在尝试获取所有COLUMNNAME 列表,其中WHITELISTED 为真。 我得到了select json_extract(column_metadata, '$[*].COLUMNNAME') from myTable,它返回了所有以逗号分隔的列名。

但是,当我添加 where 子句时

select json_extract(column_metadata, '$[*].COLUMNNAME') from myTable
WHERE json_extract(column_metadata, '$[*].WHITELISTED') = true;

它不返回任何东西。我们如何用 json_extract 构造 where 子句?

编辑:我使用的是 MySQL 5.7,所以 JSON_TABLE() 不可用

【问题讨论】:

    标签: mysql sql mysql-5.7 mysql-json


    【解决方案1】:

    您不能使用 JSON_EXTRACT() 来执行此操作。一般来说,JSON_EXTRACT() 不能很好地搜索 JSON 对象数组的字段。您可以给 JSON_EXTRACT() 一个路径,但不能使用 JSON_EXTRACT() 在标量上下文中生成数组结果,这就是您在假设(非工作)SQL 查询中显示的内容。

    你需要的是JSON_TABLE(),它是在MySQL 8.0中引入的:

    SELECT j.COLUMNNAME
    FROM mytable, JSON_TABLE(mytable.column_metadata, '$[*]' COLUMNS(
      `ORDER` SMALLINT PATH '$.ORDER',
      READONLY BOOL PATH '$.READONLY',
      COLUMNNAME VARCHAR(64) PATH '$.COLUMNNAME',
      COLUMNTYPE VARCHAR(20) PATH '$.COLUMNTYPE',
      FILTERABLE BOOL PATH '$.FILTERABLE',
      SUMMARYVIEW BOOL PATH '$.SUMMARYVIEW',
      WHITELISTED BOOL PATH '$.WHITELISTED'
    )) AS j
    WHERE j.WHITELISTED = true
    

    给定示例数据的结果:

    +-------------+
    | COLUMNNAME  |
    +-------------+
    | name        |
    | description |
    +-------------+
    

    在我看来,JSON_TABLE() 是一个 PITA。 每次你想在 JSON 数据的特定字段中搜索特定值时,你都必须写出冗长、复杂的语法。

    使用普通的表和列而不是 JSON 会容易得多。

    CREATE TABLE column_metadata (
      `ORDER` SMALLINT,
      READONLY BOOL,
      COLUMNNAME VARCHAR(64),
      COLUMNTYPE VARCHAR(20),
      FILTERABLE BOOL,
      SUMMARYVIEW BOOL,
      WHITELISTED BOOL
    );
    

    那么你的查询就更容易开发和阅读了:

    SELECT COLUMNNAME FROM column_metadata WHERE WHITELISTED = true;
    

    您还可以通过在普通表中定义索引来优化查询,而在 JSON 数组上创建索引会令人困惑,并且需要更多 new features introduced in MySQL 8.0.17。

    【讨论】:

    • 我使用的是 MySQL 5.7。没有 JSON_TABLE()。我也无法选择将 Json 拆分为一个表,因为它是旧表中的一列。考虑到我的限制,寻找一种方法来做到这一点
    • 对不起,我帮不上忙。 JSON 在关系数据库中是个坏主意。
    猜你喜欢
    • 2015-02-11
    • 2020-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-14
    • 1970-01-01
    相关资源
    最近更新 更多