【问题标题】:MySQL delete specified rows from a table when the data from yesterday matches the data from today当昨天的数据与今天的数据匹配时,MySQL 从表中删除指定的行
【发布时间】:2013-01-29 01:32:18
【问题描述】:

我有一些数据存储在一个名为 MyTable 的 MySQL 表中,如下所示:

+----------+-----------+---------------------+
|    my_id |    amount | updated             |
+----------+-----------+---------------------+
|   105415 |        81 | 2013-02-13 00:00:00 |
|   105414 |        33 | 2013-02-13 00:00:00 |
|   220801 |       240 | 2013-02-13 00:00:00 |
|   105411 |       118 | 2013-02-13 00:00:00 |
|   105411 |       118 | 2013-02-12 00:00:00 |
|   220801 |       240 | 2013-02-12 00:00:00 |
|   105414 |        33 | 2013-02-11 00:00:00 |
|   105415 |        81 | 2013-02-11 00:00:00 |
+----------+-----------+---------------------+

我想做的是删除昨天 (2013-02-12) 中与今天 (2013-02-13) 具有相同 my_id 和数量的所有行。

我知道如何选择今天的所有数据:

SELECT * FROM 'MyTable' WHERE 'updated' = CURDATE()

我知道如何选择昨天的所有数据:

SELECT * FROM 'MyTable' WHERE 'updated' = CURDATE()-1

我知道 DELETE 命令的语法 (DELETE FROM 'MyTable' WHERE...)。

如何删除昨天和今天 my_id 和 amount 匹配的行?

在给出的示例中,我想删除这些行:

|   105411 |       118 | 2013-02-12 00:00:00 |
|   220801 |       240 | 2013-02-12 00:00:00 |

我想保留这些行:

+----------+-----------+---------------------+
|    my_id |    amount | updated             |
+----------+-----------+---------------------+
|   105415 |        81 | 2013-02-13 00:00:00 |
|   105414 |        33 | 2013-02-13 00:00:00 |
|   220801 |       240 | 2013-02-13 00:00:00 |
|   105411 |       118 | 2013-02-13 00:00:00 |


|   105414 |        33 | 2013-02-11 00:00:00 |
|   105415 |        81 | 2013-02-11 00:00:00 |
+----------+-----------+---------------------+

【问题讨论】:

  • 不是处理症状,而是解决原因:为什么要生成这样一个重复的条目集?对 my_id 和 amount 使用唯一约束,并在保存数据时仅更新 ON DUPLICATE KEY-Clause 中的日期。
  • dognose,我已经按照你的建议修复了我的脚本,但它仍然给我留下了一个需要从我的问题中查询的数据库来清理。

标签: mysql database join inner-join


【解决方案1】:

对@sgeddes 的回答稍作修改,我认为这对您的回答更准确:

无论如何,请把@sgeddes 的答案作为正确答案,因为他的回答引导了这一点:

DELETE t1 FROM MyTable AS t1, MyTable as t2
WHERE t1.updated = CURDATE()-1
  AND t2.updated =  CURDATE()
  AND t2.my_id = t1.my_id
  And t2.amount = t1.amount;

如果你有一个主键,你也可以使用它(这是我更喜欢的 SQL)

DELETE FROM MyTable 
WHERE  updated = CURDATE()-1 
  AND (my_id,amount) in (select my_id,amount 
                         from MyTable
                         where updated = CURDATE());

【讨论】:

    【解决方案2】:

    这样的事情应该可以工作:

    DELETE M
    FROM MyTable M
        INNER JOIN MyTable M2 ON
            M.My_Id = M2.My_Id AND  
            M.amount = M2.amount AND  
            M2.Updated = DATE_ADD(M.Updated, INTERVAL 1 DAY)
    

    这是更新后的 Fiddle,上面包含您的示例数据:http://sqlfiddle.com/#!2/5e288/1

    以及删除后的结果:

    MY_ID   AMOUNT  UPDATED
    105415  81      February, 13 2013 00:00:00+0000
    105414  33      February, 13 2013 00:00:00+0000
    220801  240     February, 13 2013 00:00:00+0000
    105411  118     February, 13 2013 00:00:00+0000
    105414  33      February, 11 2013 00:00:00+0000
    105415  81      February, 11 2013 00:00:00+0000
    

    祝你好运。

    【讨论】:

    • 你错过了“and m.my_id = m2.my_id”吗?
    • @SurasinTancharoen -- 很棒的收获 -- 没有意识到这些是平等的!我更新了上面的答案。谢谢!
    • 欢迎您!但是,为了更准确地回答,最好将 'M2.Updated = DATE_ADD(M.Updated, INTERVAL 1 DAY)' 更改为 'AND M2.Updated = CURDATE() AND M.Updated = CURDATE()- 1'
    • @SurasinTancharoen -- 如果 OP 的字面意思是昨天(而不是前一天),那么是的,你的方法更安全。我假设 OP 表示前一天,需要清理将当天与前一天进行比较的历史数据。不过不用担心——感谢您的帮助:)
    • @user1464409 -- 如果您只想将今天(2/13)与昨天进行比较,您可以按照 SurasinTancharoen 的建议使用 CURDATE()。但是,如果您有还需要清理的历史数据(例如上周),请使用我在上面发布的内容。如果您遇到问题,请告诉我,我将使用 CURDATE() 更新答案。祝你好运!
    猜你喜欢
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    • 2017-02-14
    • 2022-11-15
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    • 1970-01-01
    相关资源
    最近更新 更多