出现怪异的SQL如下:
SELECT *FROM teacherWHERE DATE_FORMAT(DATE_ADD('2023-11-01',INTERVAL FLOOR(RAND() * DATEDIFF (CURDATE(), '2023-11-01')) DAY),'%Y-%m') = DATE_FORMAT(create_time, '%Y-%m');
原始需求:
查询从给定月份到现在的时间段内,查询随机某月的数据。
当前现状:
根据前面提供的SQL查出来的数据,看条目数应该是对的,但是具体的数据却不对。有没有大神看一下问题出在哪里,亦或还有否更好的思路。
创建表
create table `teacher` ( `id` int (11), `name` varchar (96), `create_time` datetime );
插入数据
insert into `teacher` (`id`, `name`, `create_time`) values('10','张三','2023-11-17 09:34:23');insert into `teacher` (`id`, `name`, `create_time`) values('12','李四','2023-10-21 09:34:55');insert into `teacher` (`id`, `name`, `create_time`) values('13','王五','2023-12-08 09:35:13');insert into `teacher` (`id`, `name`, `create_time`) values('14','赵六','2023-12-28 09:35:48');insert into `teacher` (`id`, `name`, `create_time`) values('15','孙七','2024-01-11 09:36:31');insert into `teacher` (`id`, `name`, `create_time`) values('16','钱八','2024-01-25 09:38:15');insert into `teacher` (`id`, `name`, `create_time`) values('17','老九','2024-03-07 09:38:53');insert into `teacher` (`id`, `name`, `create_time`) values('18','老十','2024-03-10 09:39:35');insert into `teacher` (`id`, `name`, `create_time`) values('19','十一','2024-03-11 09:41:36');
where 条件是每条记录执行一次, 所以每次的rand()生成的值都不相同.
可以如下试试
set @date = DATE_FORMAT(DATE_ADD('2023-11-01',INTERVAL FLOOR(RAND() * DATEDIFF (CURDATE(), '2023-11-01')) DAY),'%Y-%m');select * from teacher where @date = DATE_FORMAT(create_time, '%Y-%m');
但最好是使用 between 来当条件
你现在这这样的 SQL ,where 条件中,随机日期范围的那一部分,在每次 where 的时候都会执行一次 RAND ,所以就会有问题,要解决这个问题,那就要使得这个 RAND 只执行一次,如果是在 MySQL 8 中,可以使用 With 语句。
with mo1 as (select DATE_FORMAT(DATE_ADD('2023-11-01', INTERVAL FLOOR(RAND() * DATEDIFF(CURDATE(), '2023-11-01')) DAY), '%Y-%m') as month)SELECT *FROM teacher join mo1 on mo1.month = DATE_FORMAT(create_time, '%Y-%m')
这样,就可以获得预期的结果了。但是,这样并不好。
DATE_FORMAT(create_time, '%Y-%m')
这样将会导致 MySQL 在查询数据的时候,无法使用到索引,如果数据量大的话,查询就会很慢。虽然在 MySQL 8 中,你可以使用 函数索引,来创建索引从而提高效率。
alter table teacher add index idx_month((DATE_FORMAT(create_time, '%Y-%m')));
但是这样也不是很好的办法,更建议的是,从外部传入的参数,把日期补全,把查询改成 between 的方式,再直接为 create_time 创建索引。
SELECT *FROM teacherwhere create_time between '2024-01-01 00:00:00' and '2024-01-31 23:59:59';# 或者SELECT *FROM teacherwhere create_time >= '2024-01-01 00:00:00' and create_time < '2024-02-01 00:00:00';
问题内容: 我需要用mysql减去1个月零4天,我看到命令 完美适用于1个月但1个月零4天,使用31天对于每个月带来30、29、28的每月无效。我无法添加31 + 4,30 + 4,等等 问题答案: 使用 [docs] 像:
问题内容: 我想计算两个日期时间字段之间的月份数。 有没有比获得unix时间戳和除以2592 000(秒)并在MySQL中四舍五入更好的方法了? 问题答案: 该DATEDIFF功能可以给你的天数两个日期之间。由于…您如何定义一个月,哪个更准确?(28、29、30或31天?)
问题内容: 按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 7年前关闭。 与MySQL相比,使用MySQLi有什么优势? 问题答案: 见文档: PHP的mysqli扩展是什么? mysqli扩展或MySQL改进的扩展是为了利用MySQ
问题内容: 我有一个包含datetime列的表。我希望无论何时都返回给定日期的所有记录。换句话说,如果我的表仅包含以下4条记录,那么如果我限制为2012-12-25,则仅返回第二和第三条记录。 问题答案: 永远不要 使用像这样的选择器-它是性能杀手: 它将为所有不匹配的行(包括那些行)计算 它将无法使用索引进行查询 使用起来更快 因为这将允许索引使用而无需计算。 编辑 正如Used_By_Alre
问题内容: 我希望能够使用以下语句从mysql中获取结果: 但是我想获取限制在某个月和一年中的结果(基于用户的输入)…我试图这样做: … 一个月,但它给了错误。 在该表中,它实际上有两个日期: 和,但我注重。输入值为月份和年份。我该如何措辞根据当年那个月获得结果的SQL语句? 问题答案: 您很接近-向后进行比较(假设是DATETIME或TIMESTAMP数据类型): 注意事项: 请注意,您正在使用
问题内容: 如何使用MySQL在过去2周中使用随机日期更新列? 例如(代码实际上不起作用): 问题答案: 您可以使用以下表达式获得随机整数: 要获得i <= R <j范围内的随机整数R,请使用表达式 。例如,要获得7 <= R <12范围内的随机整数,可以使用以下语句: http://dev.mysql.com/doc/refman/5.1/en/mathematical- functions.h