我有一个如下所示的数据库:
post metrics minutes
(此示例中只有帖子ID 1的数据)
| post id | date updated local | reach |
|1 | 2018-01-01 01:00:00 | 10 |
|1 | 2018-01-01 01:05:00 | 20 |
|1 | 2018-01-01 01:15:00 | 22 |
|1 | 2018-01-01 16:05:00 | 100 |
|1 | 2018-01-02 03:00:00 | 121 |
|1 | 2018-01-02 21:00:00 | 140 |
|1 | 2018-01-04 01:00:00 | 147 |
我的系统设计用于每5分钟获取所有帖子的数据,如果覆盖率与上次为该帖子存储的时间不同,则将结果放在上表中(这样可以防止获取大量数据)这是完全一样的)。
现在有成千上万的帖子,桌子开始失去控制,使得我的网站从这张桌子加载数据时速度慢了。
所以我决定通过每天保留每个帖子的最后一行来减少数据,所以我想删除那些不是该帖子的最大date updated local
的所有行。结果将是:
| post id | date updated local | reach |
|1 | 2018-01-01 16:05:00 | 100 |
|1 | 2018-01-02 21:00:00 | 140 |
|1 | 2018-01-04 01:00:00 | 147 |
我想出了:
DELETE FROM `post metrics minutes`
WHERE EXISTS (
SELECT *
FROM `post metrics minutes` pmmtemp
WHERE pmmtemp.`post id` = `post metrics minutes`.`post id`
AND pmmtemp.`date updated local` > `post metrics minutes`.`date updated local`
AND DATE(pmmtemp.`date updated local`) = DATE(`post metrics minutes`.`date updated local`)
);
但是这给了我以下错误:
Error Code: 1093. Table 'post metrics minutes' is specified twice, both as a target for 'DELETE' and as a separate source for data
希望有人能帮助我!
答案 0 :(得分:1)
无法在同一个表上删除或更新子查询。
可以创建一个要删除的post_id的临时表。
但是首先标记记录也是如此。这样两个查询都不会相互干扰。
对于嵌套表,而不是FROM tablename
我为临时表做FROM (SELECT * FROM tablename)
。
我在这里滥用了专栏reach
。
UPDATE `post metrics minutes` p
SET p.reach = -1
WHERE EXISTS (
SELECT *
FROM (SELECT * FROM `post metrics minutes`) pmmtemp
WHERE pmmtemp.`post id` = p.`post id`
AND pmmtemp.`date updated local` > p.`date updated local`
AND DATE(pmmtemp.`date updated local`) = DATE(p.`date updated local`)
);
DELETE FROM `post metrics minutes`
WHERE reach = -1;
答案 1 :(得分:1)
根据我的评论,创建一个包含所需日期的新表通常会更快,然后删除旧表并将其替换为新表。
我的列/表名称可能与您的名称略有不同,但类似于......
CREATE TABLE my_new_table AS
SELECT x.*
FROM my_old_table x
JOIN
( SELECT post_id,MAX(dt) dt FROM my_old_table GROUP BY post_id,DATE(dt)) y ON y.post_id = x.post_id
AND y.dt = x.dt;