我在MySQL
数据库中有一个表,其中包含登录时间数据(以Unix时间/大纪元时间格式):
login_id sign_in_time sign_in_time_seconds user_id
1 1406800000 5 1
2 1406800100 0 1
3 1406800350 10 1
4 1406805426 0 145
5 1406805504 0 167
6 1406805503 30 183
我需要在2分钟内多次选择相同user_id
签名的所有行。它应该只返回可疑行,而不是最早和有效的登录。
我尝试过以下代码,但它似乎无法正常工作:
SELECT t1.*
FROM logintable t1 JOIN logintable t2 ON t1.login_id = t2.login_id
WHERE
t1.user_id = t2.user_id AND
(ABS((t1.sign_in_time+t1.sign_in_time_seconds)-(t2.sign_in_time+t2.sign_in_time_seconds) <= 120)
ORDER BY
t1.user_id ASC;
查询还应该只显示可疑的签名ins。根据顶部的列表,它应该返回以下行:
login_id sign_in_time sign_in_time_seconds user_id
2 1406800100 0 1
答案 0 :(得分:1)
你的错误在这里:
ON t1.login_id = t2.login_id
这应该是
ON t1.user_id = t2.user_id
因为您想比较登录时间的用户。
您可以简单地删除ON子句并使WHERE子句成为新的ON子句: - )
答案 1 :(得分:0)
主要问题是登录ID的条件。但是,我不认为时间比较会得到所有行:时间比较仅在登录时间结束时而不是在开头。
另外,我认为exists
更能传达查询的意图。当两分钟内有多次登录尝试时,这也可以防止重复:
SELECT t1.*
FROM logintable t1
WHERE EXISTS (SELECT 1
FROM logintable t2
WHERE t1.user_id = t2.user_id AND
(t1.sign_in_time between t2.sign_in_time and t2.sign_in_time + t2.sign_in_time_seconds + 120 or
t2.sign_in_time between t1.sign_in_time and t1.sign_in_time + t1.sign_in_time_seconds + 120
)
)
ORDER BY t1.user_id ASC;