我有这张表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
我想删除所有“旧”的行,但有一些条件:
如何使用mysql实现这一目标?
答案 0 :(得分:1)
这应该可以解决问题:
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)
您在这里做的是针对包含每个max
的最高日期的子选择(别名为supp_id
)进行联接(同时排除supp_date
所在的行未来)。通过对max
子选择进行LEFT JOIN,你会&#34;保护&#34;通过仅删除联接结果最终为supp_id
中的字段具有NULL
值的情况,所有行具有给定max
的最大日期。这是通过WHERE子句的第一部分实现的。
然后应用条件,即记录也必须早于两周,作为WHERE子句的第二部分。
答案 1 :(得分:0)
首先,您需要为您的桌子提供PK。我假设您将使用id作为PK。
您必须使用NOW()
DELETE FROM supp_props WHERE supp_date&lt;现在() - INTERVAL 2周;
如果您的表存储的日期时间与NOW()返回的时区不同,则可以使用UTC_TIMESTAMP()来获取UTC时间戳。
答案 2 :(得分:0)
您应该为表格提供一个PK列,以便轻松完成此操作。
如果没有PK,您只能使用选择子查询来选择过去但未来的所有数据,并按日期排序,然后按supp_id分组为tmp表
然后执行查询以从表中删除条件为supp_id且supp_date在tmp表中不存在的所有数据。
但这不是删除数据的好方法..仍然是PK的建议..
答案 3 :(得分:0)
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;
答案 4 :(得分:0)
感谢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
谢谢大家的帮助!