我需要统计用户在过去一小时内是否连续3次尝试登录失败。
例如
id userid status logindate
1 1 0 2014-08-28 10:00:00
2 1 1 2014-08-28 10:10:35
3 1 0 2014-08-28 10:30:00
4 1 0 2014-08-28 10:40:00
在上面的示例中,状态 0 表示尝试失败,1 表示尝试成功。
我需要一个查询来统计过去一小时内发生的状态为 0 的用户的三个连续记录。
我尝试了以下查询
SELECT COUNT( * ) AS total, Temp.status
FROM (
SELECT a.status, MAX( a.id ) AS idlimit
FROM loginAttempts a
GROUP BY a.status
ORDER BY MAX( a.id ) DESC
) AS Temp
JOIN loginAttempts t ON Temp.idlimit < t.id
HAVING total >1
结果:
total status
2 1
我不知道为什么它的状态显示为1。我还需要在登录日期和状态字段上添加一个 where 条件,但不知道它如何工作
最佳答案
对于连续计数,您可以使用用户定义的变量来记录系列值,就像在下面的查询中我使用 @g
和@r
变量,在内部查询中,我存储当前状态值,可能是 1/0,在 case 表达式中,我正在比较 @g
中存储的值。与状态列,如果它们都相等,如 @g
保存前一行值并且前一行的状态等于当前行的状态,则不要更改存储在 @r
中的值,如果这些值不匹配,如 @g <> a.status
然后增加 @r
对于 1,需要注意的一件事是,我将 order by 与 id 列一起使用,并假设它设置为 auto_increment,因此对于连续的 1s @r
值将与 @r
相同第一个状态 1 为 3,第二个状态为 1,所以 @r
将 3 直到状态更改为 0 与状态 0 相同,反之亦然
SELECT t.userid,t.consecutive,t.status,COUNT(1) consecutive_count
FROM (
SELECT a.* ,
@r:= CASE WHEN @g = a.status THEN @r ELSE @r + 1 END consecutive,
@g:= a.status g
FROM attempts a
CROSS JOIN (SELECT @g:=2, @r:=0) t1
WHERE a.`logindate` BETWEEN '2014-08-28 10:00:00' AND '2014-08-28 11:00:00'
ORDER BY id
) t
GROUP BY t.userid,t.consecutive,t.status
HAVING consecutive_count >= 3 AND t.status = 0
现在在父查询中,我按 userid
对结果进行分组我的 case 表达式的结果值为 consecutive
和status
获取每个用户连续状态的计数
One thing to note for above query that its necessary to provide the hour range like i have used between without this it will be more difficult to find exactly 3 consecutive statuses with in an hour
示例数据
INSERT INTO attempts
(`id`, `userid`, `status`, `logindate`)
VALUES
(1, 1, 0, '2014-08-28 10:00:00'),
(2, 1, 1, '2014-08-28 10:10:35'),
(3, 1, 0, '2014-08-28 10:30:00'),
(4, 1, 0, '2014-08-28 10:40:00'),
(5, 1, 0, '2014-08-28 10:50:00'),
(6, 2, 0, '2014-08-28 10:00:00'),
(7, 2, 0, '2014-08-28 10:10:35'),
(8, 2, 0, '2014-08-28 10:30:00'),
(9, 2, 1, '2014-08-28 10:40:00'),
(10, 2, 1, '2014-08-28 10:50:00')
;
正如您所看到的,从 id 3 到 5,您可以看到 userid 1 的连续 0,类似地,id 6 到 8 userid 2 也有连续的 0,并且它们在一个小时范围内,使用上面的查询您可以得到如下结果
userid consecutive status consecutive_count
------ ----------- ------ -------------------
1 2 0 3
2 2 0 3
Fiddle Demo
关于mysql - 计算具有特定状态的连续行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25563374/