删除除最新日期以外的所有行

Delete all rows but the latest date

我知道了 table supp_props:

supp_id | supp_dry_weight | supp_price | supp_date
--------+-----------------+------------+------------ 
  22    |      88.00      |   27.50    | 2015-06-25   x delete
  22    |      89.00      |   28.00    | 2015-10-18       < don't delete, while
  22    |      89.00      |   29.50    | 2015-12-20         this row here is in the future
  23    |      84.00      |   15.00    | 2015-06-23   x delete
  23    |      42.50      |   7.50     | 2015-06-25   x delete
  23    |      35.60      |   5.00     | 2015-06-29
  24    |      89.00      |   18.20    | 2015-06-25
  25    |      89.15      |   18.50    | 2015-08-05
  26    |      89.00      |   28.30    | 2015-06-25

我想删除所有 'old' 的行,但有一些条件:

如何使用 mysql 实现该目标?

首先,您需要 table 的 PK。我假设您会使用 id 作为 PK。

您将不得不使用 NOW()

从 supp_props 中删除 WHERE supp_date < NOW() - 间隔 2 周;

如果您的 table 将日期时间存储在与 NOW() returns 不同的时区,您可以使用 UTC_TIMESTAMP() 来获取 UTC 时间戳。

你应该有一个 table 的 PK 列来轻松地做到这一点..

如果没有 PK,您只能使用 select 子查询 select 所有过去但不是未来的数据,并按日期排序,然后按 supp_id 分组成为 tmp table

然后执行查询以从您的 table 中删除条件 supp_id 和 supp_date 在 tmp table.[=10= 中不存在的所有数据]

但这不是删除数据的好方法..还是按照建议PK..

这应该可以解决问题:

DELETE sp FROM supp_props AS sp
LEFT JOIN (
    SELECT supp_id, MAX(supp_date) AS max_date
    FROM supp_props
    WHERE supp_date <= DATE(NOW())
) AS max
    ON sp.supp_id = max.supp_id
    AND sp.supp_date = max.max_date
WHERE max.supp_id IS NULL
AND sp.supp_date < DATE_SUB(NOW(), INTERVAL 2 WEEK)

您在这里所做的是针对包含每个 supp_id 的最高日期的子选择(别名为 max)进行连接(同时排除 supp_date是在未来)。通过针对该 max 子选择进行 LEFT JOIN,您将 "protect" 所有具有给定 supp_id 的最大日期的行,仅删除连接结果最终具有 [=16] 的情况=] max 中字段的值。这是通过 WHERE 子句的第一部分实现的。

然后您将记录也必须早于两周的条件应用为 WHERE 子句的第二部分。

http://sqlfiddle.com/#!9/16d9d/1

DELETE t1 FROM `t1` t1
LEFT JOIN `t1` t
ON t1.supp_id = t.supp_id
    AND t1.supp_date < t.supp_date 
    AND t.supp_date < DATE_ADD(NOW(), INTERVAL -2 WEEK)
WHERE t1.supp_date < DATE_ADD(NOW(), INTERVAL -2 WEEK)
    AND t.supp_id IS NOT NULL;

感谢 Alex、Mike Brent 和 xQbert 的大力帮助和示例,我成功创建了这个查询:

DELETE sp 
FROM supp_props sp
LEFT JOIN (
   SELECT supp_id, MAX( supp_date ) AS max_date
   FROM supp_props
   WHERE supp_date < NOW()
   GROUP BY supp_id
) max
ON sp.supp_id = max.supp_id
WHERE sp.supp_date < ( DATE_SUB( CURDATE(), INTERVAL 2 week ) )
AND sp.supp_date <> max.max_date

谢谢大家的帮助!