Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
mysql删除受组限制的行_Mysql_Sql_Group By - Fatal编程技术网

mysql删除受组限制的行

mysql删除受组限制的行,mysql,sql,group-by,Mysql,Sql,Group By,我有一个很大的信息表,上面有日期和房间栏。和20亿行 现在我只想保留每个房间最后50条信息,并删除以前的信息 我可以用快速查询来完成吗 这个问题是唯一的,我没有发现任何关于在分组和有序选择上删除行的其他问题 您无法在快速查询中执行此操作。你有很多数据 我建议创建一个新表。然后,如果需要,可以替换第一个表中的数据 可能是获得50行的最有效方法-假设每个房间的日期都是唯一的: 为了让它有任何表现的希望,你需要一个关于房间、日期的索引 您也可以尝试MySQL 8+中的row_number: selec

我有一个很大的信息表,上面有日期和房间栏。和20亿行

现在我只想保留每个房间最后50条信息,并删除以前的信息

我可以用快速查询来完成吗

这个问题是唯一的,我没有发现任何关于在分组和有序选择上删除行的其他问题


您无法在快速查询中执行此操作。你有很多数据

我建议创建一个新表。然后,如果需要,可以替换第一个表中的数据

可能是获得50行的最有效方法-假设每个房间的日期都是唯一的:

为了让它有任何表现的希望,你需要一个关于房间、日期的索引

您也可以尝试MySQL 8+中的row_number:

select . . .   -- list the columns
from (select t.*, row_number() over (partition by room order by date desc) as seqnum
      from t
     ) t
where seqnum <= 50;

大规模插入比大规模更新效率更高,因为不需要记录旧数据,也不需要锁定页面和其他事情。

您可以使用排名函数获得按日期描述排序的每个组的前50名结果,因此最后一个条目将位于前50名。 然后,如果id或room和date是唯一的,并且表中没有id,则将该子查询留在表上 最后一步是过滤子查询中包含null的所有此类结果并删除这些结果。 完整代码如下所示:

DELETE T FROM YOURTABLE T
LEFT JOIN (
    SELECT  *,
        RANK() OVER (PARTITION BY
                     ROOM
                 ORDER BY
                     [DATE] DESC
                ) DATE_RANK
                ) AS T2
ON T.[DATE] = T2.[DATE]
AND T.ROOM = T2.ROOM
AND T2.DATE_RANK<=50
WHERE T2.DATE IS NULL


最有可能的快速方法是创建一个新表并复制这些记录,删除旧表并重命名..无论如何,有关性能的问题至少应该包括一个SHOW CREATE table_名称,以便我们了解您正在谈论的数据类型和可能的索引..可能的重复通常更快地构建一个新表,只保留您希望保留的记录。然后放下那张旧桌子。然后重命名并重新索引新表。
create table temp_t as 
    select . . .   -- one of the select queries here;

truncate table t;  -- this gets rid of all the data, so be careful

insert into t
   select *
   from temp_t;
DELETE T FROM YOURTABLE T
LEFT JOIN (
    SELECT  *,
        RANK() OVER (PARTITION BY
                     ROOM
                 ORDER BY
                     [DATE] DESC
                ) DATE_RANK
                ) AS T2
ON T.[DATE] = T2.[DATE]
AND T.ROOM = T2.ROOM
AND T2.DATE_RANK<=50
WHERE T2.DATE IS NULL