如何在MySQL Event中实现分组统计、求和及条件插入逻辑?
MySQL事件中实现分组求和与条件插入逻辑的解决方案
我来帮你一步步实现这个需求——从核心统计查询到封装成定时事件,全程用MySQL原生语法搞定:
第一步:先写出核心统计查询
首先我们需要生成你期望的统计结果,这里用MySQL的窗口函数来实现同auto_assign分组的总计数求和,正好匹配你要的sum列;check_count则是sum的50%向下取整(对应你示例里的11→5、7→3)。
完整的统计查询如下:
SELECT COUNT(*) AS count, in_use, auto_assign, SUM(COUNT(*)) OVER (PARTITION BY auto_assign) AS sum, FLOOR(SUM(COUNT(*)) OVER (PARTITION BY auto_assign) * 0.5) AS check_count FROM table1 WHERE group_id = 3 -- 你示例里针对group_id=3,可根据需求调整 GROUP BY in_use, auto_assign ORDER BY in_use, auto_assign;
字段说明:
count:按in_use和auto_assign分组后的记录数sum:通过窗口函数PARTITION BY auto_assign,计算同一个auto_assign分组下的总count(比如auto_assign=0的7+4=11)check_count:对sum取50%后向下取整,用FLOOR()实现符合你要求的取整逻辑
执行这个查询后,就能得到你期望的输出结果。
第二步:基于统计结果实现条件插入
接下来我们要判断:当in_use=1时,如果对应的count小于check_count,就插入记录到table2。这里用INSERT ... SELECT语法直接关联统计查询,避免中间表:
INSERT INTO table2(cli_group_id, auto_assign, percentage_value, result_value) SELECT 3 AS cli_group_id, -- 对应目标group_id,可动态调整 auto_assign, check_count, count FROM ( -- 嵌入第一步的统计查询 SELECT COUNT(*) AS count, in_use, auto_assign, SUM(COUNT(*)) OVER (PARTITION BY auto_assign) AS sum, FLOOR(SUM(COUNT(*)) OVER (PARTITION BY auto_assign) * 0.5) AS check_count FROM table1 WHERE group_id = 3 GROUP BY in_use, auto_assign ) AS stats WHERE in_use = 1 AND count < check_count;
逻辑说明:
- 内层子查询是核心统计逻辑
- 外层筛选
in_use=1的记录,并且只插入count < check_count的符合条件的行 - 插入的字段完全匹配你给出的示例语句
第三步:封装成MySQL定时事件
最后把上述插入逻辑封装成定时事件,让它自动执行。注意先确保MySQL的事件调度器已经开启:
1. 开启事件调度器(全局生效)
SET GLOBAL event_scheduler = ON;
2. 创建定时事件
比如设置每天凌晨1点执行一次(可根据你的需求调整执行频率):
DELIMITER // CREATE EVENT IF NOT EXISTS auto_insert_table2_event ON SCHEDULE EVERY 1 DAY STARTS '2024-01-01 01:00:00' -- 第一次执行时间,按需修改 ON COMPLETION PRESERVE ENABLE DO BEGIN -- 放入第二步的INSERT ... SELECT逻辑 INSERT INTO table2(cli_group_id, auto_assign, percentage_value, result_value) SELECT 3 AS cli_group_id, auto_assign, check_count, count FROM ( SELECT COUNT(*) AS count, in_use, auto_assign, SUM(COUNT(*)) OVER (PARTITION BY auto_assign) AS sum, FLOOR(SUM(COUNT(*)) OVER (PARTITION BY auto_assign) * 0.5) AS check_count FROM table1 WHERE group_id = 3 GROUP BY in_use, auto_assign ) AS stats WHERE in_use = 1 AND count < check_count; END // DELIMITER ;
事件参数说明:
EVERY 1 DAY:执行频率,可改为EVERY 1 HOUR(每小时)等STARTS:第一次执行的时间,按需设置ON COMPLETION PRESERVE:事件执行后保留,不自动删除ENABLE:创建后立即启用事件
额外注意事项
- 确保
table2已经存在,如果没有,可参考以下DDL创建:
CREATE TABLE table2 ( id INT AUTO_INCREMENT PRIMARY KEY, cli_group_id INT NOT NULL, auto_assign TINYINT NOT NULL, percentage_value INT NOT NULL, result_value INT NOT NULL );
- 执行创建事件的操作需要
EVENT权限,插入操作需要INSERT权限 - 如果需要针对所有group_id执行,只需删除内层查询的
WHERE group_id =3,并将插入时的cli_group_id改为stats.group_id即可
内容的提问来源于stack exchange,提问作者Ankit Doshi
相关产品推荐
相关产品推荐

