2017-08-17 125 views
-1

我有一个包含约200个不同ID的表格。每个ID在不同的时间戳记录中记录了大约100倍的数据。我想要为每个ID分别删除比该特定ID的最年轻记录早2天的记录。 又名,我想为每个ID至少2天的列表。有些可能会达到CURRENTDATE,其他列表可能是2天,从上个月开始。每个ID删除比最新记录旧2天的记录

将这项工作?:

> DELETE FROM loggingTable WHERE (DATE_SUB(MAX(T_log),INTERVAL 48 HOUR)> T_log) GROUP BY ID 

我不想删除我的数据....

+2

_“我不想删除我的数据....”_ - 然后创建一个_copy_,然后测试... – CBroe

+0

@CBroe。我的意思是:我不想删除太多的数据,并假设我做了我所期望的。 – drB

+0

然后创建一个可以验证的仔细测试条件。如果错误,请将测试环境中的数据恢复到之前的状态(您创建备份的状态),然后重试。这叫做单元测试你的代码,并且是编码的一部分。是的,如果你有经验的话,你可能会事先确定某个特定的代码只会通过查看它的工作,但通常这个技能通过大量的测试和试验和错误。由于我们无法看到您的数据,所以很难知道您的查询是否可以在其上运行,无论如何 – ADyson

回答

0

当你不想意外删除你的数据,接近在这个问题以下方式(从最坏到最佳):

  1. 创建您的数据的副本并在其上进行工作。
  2. 在交易中进行操作。这将工作像

    START TRANSACTION; 
    DELETE ...; 
    SELECT ...; /* check if everything worked as expected*/ 
    /*if yes...*/ 
    COMMIT; /* this writes your changes on disk */ 
    /*if not, don't do a commit, but instead...*/ 
    ROLLBACK; /* this undoes all the statements in the transaction */ 
    
  3. 第一写下您DELETE语句作为SELECT声明。然后检查将被删除的内容。如果没有问题,请将其转换为DELETE声明(如果愿意,可将此方法与上面的第2点结合使用)。比如像下面这样:

    SELECT 
    * 
    FROM loggingTable lt 
    JOIN (SELECT ID, MAX(T_log)AS max_log FROM loggingTable GROUP BY ID) AS m ON lt.ID = m.ID 
    WHERE lt.T_log < m.max_log - INTERVAL 2 DAY; 
    

    如果看起来不错:

    DELETE lt.* 
    FROM loggingTable lt 
    JOIN (SELECT ID, MAX(T_log)AS max_log FROM loggingTable GROUP BY ID) AS m ON lt.ID = m.ID 
    WHERE lt.T_log < m.max_log - INTERVAL 2 DAY; 
    

当然,你可以结合方法2和3 1以及;-)

一些附加解释:我将查询加入表格的原因是,您不能在WHERE子句中使用聚合函数(如MAX())。 SQL语句进行评估是这样的:

  1. FROM
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. ORDER BY
  6. 选择

因为where子句之前评估group by子句中,您无法访问聚合te功能在那里。它们与group by子句一起引入。

+0

谢谢,我明白now.lt.T_log指向原始表,而m.max_log指向JOIN。按ID分组。这就是我一直在寻找的。 – drB