MySQL插入查询后att_punch序列未保留,如何维持指定顺序?
问题:SQL插入记录时att_punch字段序列不保留,'ss'被排到首位
我用SQL向attendance_student表插入记录,执行后att_punch字段的序列没有保留预期顺序——原本应该放在末尾的'ss'键,保存后却跑到了首位,推测是分组处理时自动排序导致的。希望能维持指定的序列顺序,求解决办法。
我尝试过以下代码,但没有效果:
SET SESSION group_concat_max_len = 1000000; INSERT INTO attendance_student (class_id, month_id, attendance_details, created_at, updated_at) SELECT class_id, DATE_FORMAT(attendance_date, '%m') AS month_id, CONCAT('[', GROUP_CONCAT( CONCAT( '{"att_date": "', DATE_FORMAT(attendance_date, '%d-%m-%Y'), '",', '"att_status": "', attendance_status, '",', '"att_punch": ', IFNULL(JSON_ARRAY(JSON_OBJECT( 'did', '0', 'pat', IFNULL(DATE_FORMAT(created_at, '%d-%m-%Y %H:%i:%s'), ''), 'ss', IFNULL(bio_punch_details, '') )), JSON_ARRAY()), '}' ) ORDER BY attendance_date -- Added order by attendance_date SEPARATOR ', ' ) , IFNULL(CONCAT(', {"ss": "', IFNULL(bio_punch_details, ''), '"}'), '') -- Added screenshot details , ']' ) AS attendance_details, NOW() AS created_at, NOW() AS updated_at FROM student_attendance_daily GROUP BY class_id,month_id;
原因分析
问题出在JSON_OBJECT()函数上:MySQL的JSON_OBJECT()会自动按键名的字典序(ASCII顺序)排序键值对,完全忽略你传入的参数顺序。你原本想按did→pat→ss的顺序排列,但函数会强制重新排序,导致'ss'的位置不符合预期。
解决办法
放弃使用JSON_OBJECT(),改为手动拼接JSON字符串,这样就能完全控制键的顺序,不会被自动排序。修改后的代码如下:
SET SESSION group_concat_max_len = 1000000; INSERT INTO attendance_student (class_id, month_id, attendance_details, created_at, updated_at) SELECT class_id, DATE_FORMAT(attendance_date, '%m') AS month_id, CONCAT('[', GROUP_CONCAT( CONCAT( '{"att_date": "', DATE_FORMAT(attendance_date, '%d-%m-%Y'), '",', '"att_status": "', attendance_status, '",', '"att_punch": ', IFNULL( CONCAT('[', '{"did": "0",', '"pat": "', IFNULL(DATE_FORMAT(created_at, '%d-%m-%Y %H:%i:%s'), ''), '",', '"ss": "', IFNULL(bio_punch_details, ''), '"}' ), ']'), '[]' ), '}' ) ORDER BY attendance_date SEPARATOR ', ' ) , IFNULL(CONCAT(', {"ss": "', IFNULL(bio_punch_details, ''), '"}'), '') , ']' ) AS attendance_details, NOW() AS created_at, NOW() AS updated_at FROM student_attendance_daily GROUP BY class_id,month_id;
关键修改点
- 把原来的
JSON_ARRAY(JSON_OBJECT(...))替换成手动拼接的数组和对象字符串,严格按照did→pat→ss的顺序拼接键值对 - 用
IFNULL(..., '[]')替代原来的IFNULL(..., JSON_ARRAY()),保持空值时的格式一致性
这样处理后,att_punch里的键顺序会完全按照你指定的方式保留,不会再出现自动排序的问题。
内容的提问来源于stack exchange,提问作者timp bill
相关产品推荐
相关产品推荐

