根据相邻行的值删除MySQL中的行

时间:2012-11-07 01:45:32

标签: mysql sql-delete

我的表格如下所示:

eventId    activity    timestamp
1          0           2012-10-22 20:10:00
2          0           2012-10-22 20:10:20
3          1           2012-10-22 20:11:25
4          1           2012-10-22 20:12:20
5          1           2012-10-22 20:12:22
6          0           2012-10-22 20:12:30  <--
7          1           2012-10-22 20:12:25  <--
8          0           2012-10-22 20:14:46
9          0           2012-10-22 20:14:48
10         1           2012-10-22 20:15:45
11         0           2012-10-22 20:16:00
12         0           2012-10-22 20:17:00
13         0           2012-10-22 20:17:13

我想删除活动为0的每一行,并且不是按时间顺序排在活动1的行旁边。所以从这个例子中我将删除eventID为1,8,12和13的行。这是可能的将事件异步插入表中,如第6行和第7行所示。

我知道我可以循环执行此操作,方法是检查每一行并发出查询以在符合我的条件时删除它,但效率非常低。我想知道是否可以在一个查询中完成所有操作。

好像我可以做类似的事情

delete from mytable
where activity = 0
and (rownumber()+1).activity = 0
and (rownumber()-1).activity = 0
order by timestamp

这很简单,但我不认为这样的功能是可行的。

1 个答案:

答案 0 :(得分:2)

以下是您可以选择要保留的所有记录的方法:

select m.eventId
from (
  select t1.eventId, 
      max(t2.timestamp) as previousTime,
      min(t3.timestamp) as nextTime
  from mytable t1
  left outer join mytable t2 on t1.eventId <> t2.eventId and t2.timestamp < t1.timestamp
  left outer join mytable t3 on t1.eventId <> t3.eventId and t3.timestamp > t1.timestamp
  group by t1.eventId
) m
left outer join mytable tb on m.previousTime = tb.timestamp
left outer join mytable ta on m.nextTime = ta.timestamp
where tb.activity = 1
    or ta.activity = 1

SQL Fiddle Example

然后您可以执行以下操作:

delete from mytable
where mytable.eventId not in ( ... ) <--above query