我创建了一个"登录"用于存储用户登录详细信息的表,如下所示(带有示例数据)。
CREATE TABLE Login ( id int(11) NOT NULL AUTO_INCREMENT, userid int(11) DEFAULT NULL, logintime timestamp NULL DEFAULT CURRENT_TIMESTAMP, status tinyint(4) NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;
INSERT INTO Login (id, userid, logintime, status)
values (1, 1, '2014-12-19 16:27:46', -1),
(2, 1, '2014-12-19 16:31:18', -1),
(3, 1, '2014-12-19 16:31:27', -1),
(4, 1, '2014-12-19 16:31:29', -1),
(5, 1, '2014-12-19 16:31:41', 1),
(6, 2, '2014-12-19 16:32:01', -1),
(7, 2, '2014-12-19 16:32:03', -1),
(8, 1, '2014-12-19 16:32:06', -1),
(9, 1, '2014-12-19 16:32:37', -1),
(10, 2, '2014-12-19 16:32:58', 1),
(11, 3, '2014-12-19 16:33:05', 1),
(12, 4, '2014-12-19 16:33:10', -1),
(13, 4, '2014-12-19 16:33:11', -1),
(14, 4, '2014-12-19 16:33:11', -1),
(15, 5, '2014-12-19 16:33:16', -1),
(16, 3, '2014-12-19 16:33:19', 1),
(17, 3, '2014-12-19 16:34:39', 1);
在此示例中,字段status = 1显示成功登录,而status = -1显示登录失败。
在这里,我想删除重复的失败登录(例如,状态= -1)记录,除了第一条记录中的记录。
在我的情况下,用户1使用loginid 2,3,4的方法应该被删除,因为它是在loginid 1之后的一个sequance中。
然后用户1登录成功登录5(状态= 1),所以应该保留,
在用户1的loginid 9之后,还应删除,因为它是重复记录。
我想为每个用户执行此操作,此表至少有1400万(非常巨大),我想用DELETE查询来做。他们的任何查询都是这样做的吗?
答案 0 :(得分:1)
首先,我建议您不要将其视为delete
。而是将所需数据复制到另一个表,截断表,然后重新插入。
我建议使用变量来获得你想要的东西。以下标识您想要的记录:
select l.*
from (select l.*,
(@rn := if(@id = id and status = -1, @rn + 1,
if(@id := id, 1, 1)
)
) as rn
from login l cross join
(select @rn := 0, @id := 0) vars
order by id
) l
where seqnum = 1 or status = 1;
注意:测试此查询以确保它确实可以执行您想要的操作。
要使用它:
create table tmp_login as
select l.*
from (select l.*,
(@rn := if(@id = id and status = -1, @rn + 1,
if(@id := id, 1, 1)
)
) as rn
from login l cross join
(select @rn := 0, @id := 0) vars
order by id
) l
where seqnum = 1 or status = 1;
truncate table login;
insert into login(id, userid, logintime, status)
select id, userid, logintime, status
from tmp_login;
答案 1 :(得分:0)
我写了这个查询,请先试试(先备份,哈哈):
DELETE FROM Login
WHERE id NOT IN (
SELECT id
FROM (
SELECT DISTINCT LoginDelete.id
FROM Login LoginDelete
LEFT JOIN Login LoginIgnore
ON LoginIgnore.userid = LoginDelete.userid
AND LoginIgnore.status = LoginDelete.status
AND LoginIgnore.id < LoginDelete.id
WHERE LoginDelete.status = -1
AND LoginIgnore.id IS NULL
) as idList
)
此查询将执行的操作是删除每个用户的每个状态= -1,但第一次记录除外。我使用了id,因为它应该是唯一的,如果在同一时间失败两次,则可以重复登录时间。
问候。