如何在MySQL中新增列判断last_sent_date是否在近30天内?
MySQL实现大数据量日期判断列需求方案
MySQL完全可以处理3500万条记录的这类需求,比Excel更适合大数据量场景,以下分两种场景给出具体语句:
场景1:临时查询时计算列(不修改表结构)
如果不需要永久存储该列,仅在查询时动态计算结果,可使用IF函数快速实现:
SELECT email, last_sent_date, -- 判断last_sent_date是否在过去30天内,是返回1,否则返回0 IF(last_sent_date >= DATE_SUB(CURDATE(), INTERVAL 30 DAY), 1, 0) AS sent_last_30_days FROM your_table_name; -- 替换为你的表名
说明:
CURDATE()获取当前系统日期DATE_SUB(CURDATE(), INTERVAL 30 DAY)计算出30天前的日期- 若
last_sent_date为字符串类型,需先转换为日期格式,比如:STR_TO_DATE(last_sent_date, '%Y-%m-%d')
场景2:永久新增列到表中(存储计算结果)
如果需要把该列永久保存在表中,推荐使用生成列(Generated Column),MySQL会自动维护列值,无需手动更新;也可以选择先加列再批量更新。
方式1:使用生成列(推荐)
生成列会根据last_sent_date的变化自动更新sent_last_30_days的值,无需手动维护:
ALTER TABLE your_table_name -- 替换为你的表名 ADD COLUMN sent_last_30_days TINYINT(1) GENERATED ALWAYS AS ( IF(last_sent_date >= DATE_SUB(CURDATE(), INTERVAL 30 DAY), 1, 0) ) STORED; -- STORED表示存储列值,查询更快;可选VIRTUAL不存储,节省空间但查询时计算
方式2:先加列再批量更新
若不使用生成列,可先新增列,再批量更新数据。注意:3500万条数据的全量更新耗时较长,建议在业务低峰期执行,或分批更新避免锁表:
-- 第一步:新增列 ALTER TABLE your_table_name ADD COLUMN sent_last_30_days TINYINT(1) DEFAULT 0; -- 第二步:全量更新(数据量大时不推荐,易锁表) UPDATE your_table_name SET sent_last_30_days = IF(last_sent_date >= DATE_SUB(CURDATE(), INTERVAL 30 DAY), 1, 0); -- 第二步:分批更新(推荐,每次处理10万条,需表有主键id) SET @batch_size = 100000; SET @offset = 0; REPEAT UPDATE your_table_name SET sent_last_30_days = IF(last_sent_date >= DATE_SUB(CURDATE(), INTERVAL 30 DAY), 1, 0) WHERE id BETWEEN @offset AND @offset + @batch_size; SET @offset = @offset + @batch_size + 1; UNTIL ROW_COUNT() = 0 END REPEAT;
注意事项
- 确保
last_sent_date列是DATE/DATETIME类型,若为字符串需先转换格式 - 大数据量操作前建议备份表,避免操作失误
- 生成列的
STORED/VIRTUAL选项可根据业务需求选择:追求查询效率选STORED,追求存储空间选VIRTUAL
内容的提问来源于stack exchange,提问作者John Beasley
相关产品推荐
相关产品推荐

