【问题标题】:Stringify a JSON array in MySQL在 MySQL 中对 JSON 数组进行字符串化
【发布时间】:2023-04-05 04:00:01
【问题描述】:

我在表中有一个 JSON 列。 IE 表格

    column
---------------
[2,5,7,21,1,54,12]

现在它为以下查询返回数组。

select column from table

输出 => [2,5,7,21,1,54,12]

我想要的是输出为“2,5,7,21,1,54,12”。

有什么建议吗?

【问题讨论】:

  • 规范化你的数据库。存储这样的序列化数据有什么意义?
  • 你可以使用嵌套的replace()函数来删除[]或者你可以使用SUBSTRING()LENGTH()的组合,见demo,应该还有更多MySQL string functions 可以做同样的事情。
  • @Cid 这是为了报告目的。我需要将它作为字符串化格式。而当数据被插入时,它需要是 JSON 数组格式。
  • @RaymondNijland :是的,这是我能想到的最后一个选项。没有 JSON 函数可以加入数组元素?
  • “我需要将它作为 stringify 格式。而当数据被插入时,它需要是 JSON 数组格式” JSON 数组格式始终使用 [] 和这听起来与 “我想要的是输出为“2,5,7,21,1,54,12”非常矛盾。”

标签: mysql sql json


【解决方案1】:

以下是查询 JSON 数组的示例:

select data from t;
+--------------------------+
| data                     |
+--------------------------+
| [2, 5, 7, 21, 1, 54, 12] |
+--------------------------+

您可以使用JSON_UNQUOTE() 将 JSON 数组转换为字符串。但它用方括号和空格格式化字符串:

select json_unquote(data) as stringified from t;
+--------------------------+
| stringified              |
+--------------------------+
| [2, 5, 7, 21, 1, 54, 12] |
+--------------------------+

您可以使用REPLACE() 删除那些不需要的字符:

select replace(replace(replace(json_unquote(data), ' ', ''), '[', ''), ']', '') as stringified from t;
+------------------+
| stringified      |
+------------------+
| 2,5,7,21,1,54,12 |
+------------------+

在 MySQL 8.0 中,您可以一次调用 REGEXP_REPLACE() 替换字符:

select regexp_replace(json_unquote(data), '[\\[\\] ]', '') as stringified from t;
+------------------+
| stringified      |
+------------------+
| 2,5,7,21,1,54,12 |
+------------------+

【讨论】:

    【解决方案2】:

    一个优雅的解决方案是使用JSON_TABLE() 和 MySQL GROUP_CONCAT() 功能。

    有了这样的数据样本:

    +--------+--------------------------------------------------------------------+
    | user   | emails (JSON)                                                      |
    +--------+--------------------------------------------------------------------+
    | user-1 | ["user-1@email-1.net", "user-1@email-2.net", "user-1@email-3.net"] |
    | user-2 | ["user-2@email-1.net"]                                             |
    | user-3 | ["user-3@email-1.net", "user-3@email-2.net"]                       |
    +--------+--------------------------------------------------------------------+
    

    如果我们要输出:

    +--------+----------------------------------------------------------------+
    | user   | emails (TEXT)                                                  |
    +--------+----------------------------------------------------------------+
    | user-1 | user-1@email-1.net // user-1@email-2.net // user-1@email-3.net |
    | user-2 | user-2@email-1.net                                             |
    | user-3 | user-3@email-1.net // user-3@email-2.net"                      |
    +--------+----------------------------------------------------------------+
    

    我们可以做到:

    WITH data_sample (user, emails) AS (
      -- Fake data build to test query
      VALUES 
        ROW ('user-1', JSON_ARRAY('user-1@email-1.net', 'user-1@email-2.net', 'user-1@email-3.net')),
        ROW ('user-2', JSON_ARRAY('user-2@email-1.net')),
        ROW ('user-3', JSON_ARRAY('user-3@email-1.net', 'user-3@email-2.net'))
    )
    SELECT ALL user, GROUP_CONCAT(email SEPARATOR ' // ') AS emails
    FROM data_sample
    CROSS JOIN JSON_TABLE(emails, '$[*]' COLUMNS (email TINYTEXT PATH '$')) AS _
    GROUP BY user;
    

    【讨论】:

      【解决方案3】:
      $array = (result from column);
      
      echo implode(",", $array); // separates array variables with a comma ",".
      

      更多:
      https://www.php.net/manual/en/function.implode.php

      【讨论】:

      • 我没有注意到这个问题中的 PHP 标签?
      • “有一个,它被删除了......” 不,从来没有 PHP 标记,这个问题从未被编辑过。
      • 我正在滚动浏览 php 标签,我可能点击了“相关”之类的东西。对于给您带来的不便,我深表歉意
      • Nop.. 它与 PHP 无关.. 但感谢@Andrew 的回答。我有后端作为nodeJS,虽然我不想循环并修改来自后端的数据..而是我希望尽可能从SQL修改它并且也不会使查询变得昂贵..
      猜你喜欢
      • 1970-01-01
      • 2014-08-05
      • 1970-01-01
      • 1970-01-01
      • 2016-11-10
      • 2018-06-27
      • 2019-06-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多