【问题标题】:Selectively remove row mysql选择性删除行mysql
【发布时间】:2013-03-21 17:15:28
【问题描述】:

我是 mysql 的新手,所以希望得到有关此方面的建议:

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

例如说 id 1 从 frm 1 到 5 是有效的,从 6 到 8 是假的(然后死掉)。另一个 id 2 从 frm 1 到 6 有效,从 7 到 9 为假,然后从 10 到结束再次有效。我只想删除 id 1 在第 6 帧到第 8 帧之间的行,而不触及 id 2。

到目前为止,我找到了所有标记为假的 ID 的最后一帧。 将视图 false_pt_last_frm 更改为 select id as tid, max(frame_number) as frm, valid as vld from ptTable where vld=1 group by tid;

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

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

【问题讨论】:

  • 嗨,埃文。是否有任何答案解决了您的问题?如果是这样,打勾是个好习惯。这有助于未来的访问者,也有利于回答者。

标签: mysql sql


【解决方案1】:

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

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. 识别有效设置为 false 的 id 并死掉。 2. 跨帧删除那些为假的 id。
【解决方案2】:

因此,您希望删除连续三个或更多帧的 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;

不过,在删除之前,我肯定会测试子查询。

【讨论】:

  • 感谢您的回复。我觉得我需要的有点不同。关键是我只需要删除那些长时间为假且从未恢复为真的 id,删除它们为假的帧中的 id。有什么建议吗?
【解决方案3】:

好的,试试这个。它需要 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);

【讨论】:

    猜你喜欢
    • 2012-07-30
    • 1970-01-01
    • 2011-06-22
    • 1970-01-01
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 2023-03-15
    相关资源
    最近更新 更多