有选择地删除行mysql

时间:2013-03-31 13:17:04

标签: mysql sql

我对mysql有点新意,所以希望得到以下建议:

我有一个包含3列的表:id(key int),frame(int)和valid(bool)。我很关键。我希望在有效标志在一定数量的帧之后从false变为true(它消失)时删除所有id(行)。如果帧在最大帧数(已知)内没有将其有效性从false更改为true,则不会在下一帧上更新,因此会死亡。 Id对于所有帧都是全局唯一的,每帧有多个ID。

e.g。假设id 1从frm 1到5有效,而false从6到8(然后死亡)。另一个id 2从frm 1到6有效,而7到9有效,然后从10到有效再次有效。我想只删除第6帧到第8帧之间的id 1行而不触及id 2。

到目前为止,我已经找到了标记为false的所有id的最后一帧。 将视图false_pt_last_frm改为 选择id为tid,max(frame_number)为frm,在ptTable中有效为vld,其中vld = 1 group by tid;

然后我想将ptTable与视图false_pt_last_frm连接,以查找视图中在frm + 1帧上有效的所有点,并从视图中找到该集合之外的ID并将其删除。但我坚持这一点。

这是一个很好的方法吗?请举例说明如何有效地做到这一点。

3 个答案:

答案 0 :(得分:0)

我不确定我是否理解正确。但我想你只是想要这个?

DELETE FROM <YOUR TABLE> WHERE FRAME = false AND id = <whatever ID you want to target>;

如果没有,请澄清问题,也许?

否则可能:

DELETE FROM <YOUR TABLE> WHERE FRAME = false AND id < (SELECT max(id) from <your table>);

甚至

DELETE FROM <YOUR TABLE> WHERE FRAME = false AND id = (SELECT max(id)-1 from <your table>);

如果您想要在最新的那个之前直接...

答案 1 :(得分:0)

因此,您希望删除连续三个或更多帧的valid = false序列。第一个问题是确定一行中“假”值的数量。我们可以使用相关子查询来执行此操作:

select t.*,
       ((select count(*) from t t2 where t2.id = t.id and t2.frame <= t2.frame and t2.valid = false) -- num falses before this frame, including this frame +
        (select count(*) from t t2 where t2.id = t.id and t2.frame > t2.frame and t2.valid = false) -- num falses after this frame
       ) as numFalsesInRow
from t
where t.valid = false

第一个子查询计算之前的数字,第二个子计数计算之后的数字。

现在,将其放入连接查询中,如下所示:

delete t
from t inner join
     (select t.*,
             ((select count(*) from t t2 where t2.id = t.id and t2.frame <= t2.frame and t2.valid = false) -- num falses before this frame, including this frame +
              (select count(*) from t t2 where t2.id = t.id and t2.frame > t2.frame and t2.valid = false) -- num falses after this frame
             ) as numFalsesInRow
      from t
      where t.valid = false
    ) t2
    on t.id = t2.id and t.frame = t2.frame and t2.numFalsesInRow = 3;

但是,在进行删除之前,我肯定会测试子查询。

答案 2 :(得分:0)

好的,试试这个。它需要MySQL中的临时表。在其他DBMS中可能不是这样:

create table temp as (
    select a.id 
    from ptTable a 
    where a.frame = (
            select max(b.frame) 
            from ptTable b 
            where a.id = b.id) 
    and a.valid = false) ;

delete from ptTable where id in (select id from temp);