Knex 中从 MySQL DATETIME 列按日期筛选数据的技巧

说白了,在Knex里筛MySQL DATETIME日期得用whereRaw加DATE()函数,不能直接用JS date或拼字符串。
这事复杂在SQL注入和数据库函数用法上。

先说最重要的,DATE()函数是关键——去年我们跑那个项目,直接用.where(created_at, '=', '2 02 2 -08 -1 5 ')结果只捞到精确到凌晨的数据,因为MySQL把字符串当'2 02 2 -08 -1 5 00:00:00'解析了。
另外一点,参数绑定是王道,比如whereRaw('DATE(created_at)=?', [targetDate]),去年我们接用户输入日期时,硬用"2 02 2 -08 -1 5 "直接拼接,结果一个特殊符号就SQL注入了。
还有个细节挺关键的,像筛选2 02 2 年8 月时,用whereRaw('YEAR(created_at)=? AND MONTH(created_at)=?', [2 02 2 , 8 ])效率更高,比BETWEEN精准多了。

我一开始也以为直接用DATE(created_at)=CURRENT_DATE就行,后来发现MySQL的CURRENT_DATE是带时区的,结果跨时区查询全乱套。
等等,还有个事,如果表里created_at数据量超千万,建议加个DATE(created_at)索引,否则用DATE()函数真会雪崩效应,把整个查询拖垮。

提醒个坑:时区转换用CONVERT_TZ()时,参数顺序别搞反了,'源时区','目标时区',上次测试踩过。

建议试试参数绑定+DATE函数,绝对值得。

如何用MySQL查询一年内下单天数最多的200位用户?

哎呦,这查询一年内下单天数最多的2 00位用户,其实也就这么几步。
首先,你看这个核心SQL语句,得改一下时间范围,得用实际的日期。
比如你要查2 02 4 年1 月1 日到2 02 5 年1 月1 日的,你就把那里面的日期改了。

然后,这个按用户分组统计下单天数,得用GROUP BY user_id,这样每个用户的订单就分开了。
再通过COUNT(DISTINCT date)算出每个用户在一年内不重复的下单天数,这样就避免了同一天多次下单的问题。

排序和截取结果嘛,ORDER BY下单天数 DESC就是按下单天数从多到少排,LIMIT 2 00就是只取前2 00个。

说到性能优化,首先得看索引。
在(date, user_id)上建个复合索引,这样WHERE条件和GROUP BY的时候就能快多了。
如果复合索引不行,就单独给date和user_id建索引。

查询语句优化嘛,得保证WHERE条件能用上索引,别让数据库全表扫描。
如果数据量大,可以用子查询先筛选出目标时间范围内的用户,再统计下单天数。

数据结构优化,比如可以预计算存储,比如做个用户下单天数统计表,定时任务更新,这样查询时就直接查这个表。
还可以按时间分区,比如按月分区订单表,减少查询时扫描的数据量。

注意事项,比如日期格式要统一,别到时候格式对不上。
数据量大了,得测试索引效果,必要时得分库分表或者用分布式查询。

业务逻辑也得确认一下,比如下单天数是不是得排除退款订单或者特定状态的订单,这个得看具体需求。

反正,通过这些方案,应该能高效准确地找到下单天数最多的2 00位用户,性能也能保证。
我当时也没想明白这些细节,不过现在看起来挺简单的。

mysql按24小时,时间点查询

用DATE_FORMAT按小时分组统计。
比如电商订单表按小时看销量。
SQL: SELECT DATE_FORMAT(order_time, '%H') AS hour, COUNT() AS count FROM orders WHERE DATE(order_time) = CURDATE() GROUP BY hour ORDER BY hour;
用HOUR提取小时。
比如监控日志按小时看错误数。
SQL: SELECT HOUR(log_time) AS hour, COUNT() AS errors FROM logs WHERE DATE(log_time) = CURDATE() GROUP BY hour ORDER BY hour;
用BETWEEN查特定小时。
比如查下午2 点到3 点订单。
SQL: SELECT FROM orders WHERE DATE(order_time) = CURDATE() AND HOUR(order_time) BETWEEN 1 4 AND 1 5 ;
别用UNIX_TIMESTAMP取当前时间。
应用层脚本更准。
比如Python: timestamp = int(time.time())
你自己掂量。