删除除最新日期以外的所有行
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' 的行,但有一些条件:
- 一行必须超过两周才能删除。
- 如果没有包含更新日期的行,则不应将其删除。
- 可能有未来的行,如果是这样,该行不应被视为 'more current' 日期(对于上述规则)。
如何使用 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
谢谢大家的帮助!
我知道了 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' 的行,但有一些条件:
- 一行必须超过两周才能删除。
- 如果没有包含更新日期的行,则不应将其删除。
- 可能有未来的行,如果是这样,该行不应被视为 'more current' 日期(对于上述规则)。
如何使用 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
谢谢大家的帮助!