Mysql只保留每个值每个值的最高值

时间:2018-03-21 14:38:59

标签: mysql

我有一个如下所示的数据库:

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

希望有人能帮助我!

2 个答案:

答案 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;