MYSQL 订单查询求助
假设有一张订单表 A,有下单时间和 IP,要求查出任意 30 分钟内同一 IP 交易超过 20 次的记录,该怎么写?自己想的是 group by ip,但是怎么控制任意 30 分钟以内呢
假设有一张订单表 A,有下单时间和 IP,要求查出任意 30 分钟内同一 IP 交易超过 20 次的记录,该怎么写?自己想的是 group by ip,但是怎么控制任意 30 分钟以内呢
1. 一秒一秒往前推,查 3600 次能把时间往前推 1h,后台查完另存起来,以后查这个新表。
2. distinct ip,循环处理,同一个 ip 一条记录查一次半小内的数据 count, > 20 处理下一个 ip, 否则 下一条不同于上条时间的记录。后台查完另存起来,以后查这个新表。
group by a.ip,a.下单时间 count(b.下单时间)
传送门
https://muguayuan.com/2020/16111.html
按时间分组 ,having 过滤 再关联?
这是按 1 天分组的 group by,查出来是 1 天下单超过 20 单的,所有 ip:
GROUP BY DATE_FORMAT(create_time, ‘%Y-%m-%d’)
having count(*)> 20
这是按 5 秒分组的
SELECT id,time,count(1),second(time),floor(second(time)/5) FROM `personcount` GROUP BY DATE_FORMAT( concat(date(time),’ ‘,hour(time),’:’,minute(time),’:’,floor(second(time)/5)) ,’%Y-%m-%d %H:%i:%s’);
1:比较简单,时间过滤,group by+having
2:可以以记录顺序倒序,做个子查询汇总当前记录前面 30 分钟的相同 ip 的数据,效率可能低一点,但是肯定可行。
流计算?
窗口按时间移动的需求
显然用 redis 写个 key+ttl 就好解决的问题
例如每 5 分钟内 每个用户使用固定 key
用户交易成功 incr 记录次数
每次都往前推 4 个 key 去计算和是否满足大于 20 次总量 ,如果超过,记录到异常 list 当中备查即可
如果精度要求高那就每 1 分钟一个固定 key
这实现不管是 30 分钟 1 个小时 6 个小时 12 个小时都可以做
sql 去做这个事…想想都蛋疼
SELECT iprdertime, c
FROM (
SELECT CONCAT(o1.ip, o1.ordertime) AS iprdertime, count(*) AS c
FROM orders o1
JOIN (
SELECT ip, ordertime
FROM orders
) o2
ON o1.ip = o2.ip
AND o1.ordertime >= o2.ordertime
AND o1.ordertime < o2.ordertime + 1800
GROUP BY CONCAT(o1.ip, o1.ordertime)
ORDER BY o1.ordertime
) oc
WHERE c >= 20
只测试了一小部分数据,性能可能比较低,但满足你的需求,可以通过前置筛选的方法减少查询量,如果是用来监控的,可以每天运行一次(查询前 24.5 小时内新增的数据)