You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写MySQL查询语句实现按group列分组日志表并生成自定义列

没问题,这就给你搞定这个MySQL查询需求!针对你的log表,我们可以分两种核心场景来实现:一是按group分组合并同组的JSON键值对,二是把这些JSON的键单独拆成列展示。下面是具体的实现方案,分版本说明兼容性:

一、按group分组合并成单个JSON对象

方案A:MySQL 8.0+版本(推荐,支持多键JSON)

MySQL 8.0引入的JSON_TABLE函数可以轻松拆分JSON的键值对,再结合JSON_OBJECTAGG聚合函数就能合并成完整的JSON对象:

SELECT 
  `group`,
  JSON_OBJECTAGG(key_name, value) AS merged_response
FROM (
  -- 先拆分每个response的键和对应值
  SELECT 
    l.`group`,
    jk.key_name,
    JSON_EXTRACT(l.response, CONCAT('$.', jk.key_name)) AS value
  FROM log l
  JOIN JSON_TABLE(
    JSON_KEYS(l.response),
    '$[*]' COLUMNS(key_name VARCHAR(255) PATH '$')
  ) jk
) AS extracted_keys_values
GROUP BY `group`;

这个查询会先把每条记录的response拆成key_name和value的行,再按group聚合,用JSON_OBJECTAGG把同组的键值对合并成一个JSON对象,正好符合你示例里的预期结果。

方案B:MySQL 5.7版本(兼容旧版,适合单键JSON)

如果你的MySQL版本是5.7(不支持JSON_TABLE),而你的每条response只有一个JSON键(就像示例数据那样),可以用GROUP_CONCAT拼接键值对再转成JSON:

SELECT 
  `group`,
  JSON_UNQUOTE(
    CONCAT('{', GROUP_CONCAT(
      CONCAT('"', JSON_UNQUOTE(JSON_KEYS(response)), '":', response)
      SEPARATOR ','
    ), '}')
  ) AS merged_response
FROM log
GROUP BY `group`;

注意:这个方法只适合每条response只有一个键的情况,如果有多个键会导致JSON格式错误。

二、将JSON键作为单独列展示

场景1:已知所有JSON键(静态列)

如果你已经明确知道所有可能出现的JSON键(比如last_name、first_name、dob),可以直接用JSON_EXTRACT提取,结合MAX(因为同组每个键只会出现一次)来聚合:

SELECT 
  `group`,
  MAX(JSON_UNQUOTE(JSON_EXTRACT(response, '$.last_name'))) AS last_name,
  MAX(JSON_UNQUOTE(JSON_EXTRACT(response, '$.first_name'))) AS first_name,
  MAX(JSON_UNQUOTE(JSON_EXTRACT(response, '$.dob'))) AS dob
FROM log
GROUP BY `group`;

场景2:未知所有JSON键(动态生成列)

如果JSON键是不固定的,需要自动识别所有出现过的键并生成列,可以用存储过程实现动态SQL:

DELIMITER //
CREATE PROCEDURE get_pivoted_log_data()
BEGIN
  DECLARE dynamic_columns TEXT;
  
  -- 自动提取所有唯一的JSON键,生成对应的列表达式
  SELECT GROUP_CONCAT(DISTINCT 
    CONCAT('MAX(JSON_UNQUOTE(JSON_EXTRACT(response, ''$.', key_name, '''))) AS ', key_name)
  ) INTO dynamic_columns
  FROM (
    SELECT JSON_UNQUOTE(JSON_KEYS(response)) AS key_name
    FROM log
  ) AS all_unique_keys;
  
  -- 拼接并执行动态SQL
  SET @sql = CONCAT('SELECT `group`, ', dynamic_columns, ' FROM log GROUP BY `group`');
  PREPARE stmt FROM @sql;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;
END //
DELIMITER ;

-- 调用存储过程获取结果
CALL get_pivoted_log_data();

这个存储过程会自动扫描所有response里的键,动态生成包含所有键的查询,无需手动维护列名。


内容的提问来源于stack exchange,提问作者kayode olayiwola

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 09:42:34