MySQL:从标准 SQL 查询返回 JSON

joh*_*nny 16 mysql json

我已经阅读了 JSON 对象和 JSON 对象类型。我只想做一个选择,它返回 JSON。我不一定要存储 JSON 对象。序列化本身不是我的问题。列是常规的 Varchar、Int 等列,没有 JSON 对象,“普通”数据库行。

我可以执行常规的旧 SELECT 并为 MySQL 返回 JSON 吗?

这不是SQL SERVER 中的FOR JSON和PostgreSQL 中的rows_for_json所做的吗?

他们似乎在这方面领先,但我不想欺骗自己。

我从 2016 年发现了这个问题:https : //stackoverflow.com/questions/35324795/mysql-5-7-return-row-as-json-using-new-json-features

Eva*_*oll 21

将一行转换为 json

在我看来,您并不想聚合 JSON。你说你想要相当于row_to_json,如果是这样,那么我建议检查更简单的JSON_OBJECT

SELECT JSON_OBJECT(
  'name_field', name_field,
  'address_field', address_field,
  'contact_age', contact_age
)
FROM contact;
Run Code Online (Sandbox Code Playgroud)

聚合 JSON

作为旁注,如果您确实需要将结果集聚合到 json。那么即将推出的 MySQL 8 将为您做到这一点。


Vér*_*ace 13

稍微弄清楚了(更习惯于 PostgreSQL,那里的事情容易得多!),但是如果您在这里查阅精美的手册,则在 下12.16.2 Functions That Create JSON Values,有该JSON_ARRAY功能,但实际上并没有多大用处 - 至少在这种情况下!

要回答这个问题"select and it return JSON",有两种方法可以做到这一点,都相当痛苦!

你可以

  • 使用“hack” - 请参阅此处的 db-fiddle ,

  • 或者在这里使用一个新的 MySQL 提供的 JSON 函数 - 具有讽刺意味的是,这似乎比 hack 本身更像是一个 hack!仅适用于 MySQL!:-)(在这里小提琴)。

两个答案都使用 MySQLGROUP_CONCAT函数 -这篇文章有帮助。您可能希望将group_concat_max_len系统变量设置为比其默认值多一点(微不足道的 1024)!

可以想象,第一个查询很混乱(DDL并且DML在此答案的底部):

SELECT CONCAT('[', better_result, ']') AS best_result FROM
(
SELECT GROUP_CONCAT('{', my_json, '}' SEPARATOR ',') AS better_result FROM
(
  SELECT 
    CONCAT
    (
      '"name_field":'   , '"', name_field   , '"', ',' 
      '"address_field":', '"', address_field, '"', ','
      '"contact_age":'  , contact_age
    ) AS my_json
  FROM contact
) AS more_json
) AS yet_more_json;
Run Code Online (Sandbox Code Playgroud)

结果:

[{"name_field":"Mary","address_field":"address one","contact_age":25},{"name_field":"Fred","address_field":"address two","contact_age":35},{"name_field":"Bill","address_field":"address three","contact_age":47}]
Run Code Online (Sandbox Code Playgroud)

这是正确的,但是,让我们面对现实,有点噩梦!

然后是 MySQLJSON_ARRAY()方法(甚至更混乱 - 感谢 MySQL 为您(不存在)实现该TRANSLATE()功能!)。

SELECT
CONCAT
('[', REPLACE
  (
    REPLACE
    (
      GROUP_CONCAT
      (
        JSON_ARRAY
        (
          'name_field:', name_field, 
          'address_field:', address_field, 
          'age_field:', contact_age
        ) SEPARATOR ','
      ), '[', '{'
    ), ']', '}'
  ), ']'
) 
AS best_result2 
FROM contact
Run Code Online (Sandbox Code Playgroud)

结果一样!

====  TABLE CREATION and INSERT DDL and DML ============

    CREATE TABLE contact
    (
         name_field VARCHAR  (5) NOT NULL,
      address_field VARCHAR (20) NOT NULL,
      contact_age   INTEGER      NOT NULL
    );

    INSERT INTO contact
    VALUES
    ('Mary', 'address one',   25),
    ('Fred', 'address two',   35),
    ('Bill', 'address three', 47);
Run Code Online (Sandbox Code Playgroud)


小智 7

对于一组 JSON 对象(查询中每行一个对象),您可以执行以下操作:

SELECT JSON_ARRAYAGG(JSON_OBJECT("fieldA", fieldA, "fieldB", fieldB)) 
  FROM table;
Run Code Online (Sandbox Code Playgroud)

这将导致包含所有条目的单个 JSON 数组:

[
  {
    "fieldA": "value",
    "fieldB": "value"
  },
  ...
]
Run Code Online (Sandbox Code Playgroud)

不幸的是,MySQL 不允许选择带有*. 这将是真棒,但并没有工作:

[
  {
    "fieldA": "value",
    "fieldB": "value"
  },
  ...
]
Run Code Online (Sandbox Code Playgroud)


小智 5

这将为您提供相同的答案,但代码更简单。我只是用json_objectgroup_concat简化对方的回答

select 
    concat('[',
        GROUP_CONCAT(
            JSON_OBJECT(    
                'name_field', name_field
                ,'address_field', address_field
                ,'contact_age', contact_age
                )
            SEPARATOR ',')
    ,']')
    from contact;
Run Code Online (Sandbox Code Playgroud)