SQL 维护脚本
Posted
技术标签:
【中文标题】SQL 维护脚本【英文标题】:SQL Maintenance Script 【发布时间】:2011-03-25 17:24:55 【问题描述】:我有一张表格,表格如下
GROUP_ID | FOO | BAR | DATETIME
我有一个每天晚上更新这个表的 cron。但是我想,在我的脚本结束时运行一个 sql 命令,这将确保每个 group_id 的 50 个最新行都存在,并且其他任何行都被删除。
例如:如果有 60 行 GROUP_ID = 1,我希望在运行后只剩下 50 个最近的行。如果只有 20 行 GROUP_ID = 2,则将它们全部保留。
这是否可能仅在 SQL 中实现,或者我需要在 php 中执行此操作(我的大多数应用程序都是用它构建的)
我正在运行 mysql
谢谢
【问题讨论】:
【参考方案1】:试穿一下尺寸:
DELIMITER $$
DECLARE groupCursor CURSOR FOR
SELECT GROUP_ID FROM mytable WHERE
(SELECT COUNT(*) FROM mytable WHERE GROUP_ID=GROUP_ID) > 50;
DECLARE CONTINUE HANDLER FOR NOT FOUND done = 1;
DECLARE groupID INT;
read_loop: LOOP
FETCH groupCursor INTO groupID;
IF done THEN
LEAVE read_loop;
ELSE
DELETE FROM mytable
WHERE GROUP_ID = groupID
AND DATETIME < (SELECT MIN(DATETIME) FROM mytable WHERE GROUP_ID=groupID
ORDER BY DATETIME DESC LIMIT 50)
END IF;
END LOOP;
CLOSE groupCursor$$
DELIMITER ;
更新根据下面的讨论,这里是一个存储过程 CREATE 脚本,它应该是无语法错误的。
-- --------------------------------------------------------------------------------
-- Routine DDL
-- --------------------------------------------------------------------------------
DELIMITER $$
CREATE PROCEDURE `mydb`.`maintenanceTaskDelete` ()
BEGIN
DECLARE groupCursor CURSOR FOR SELECT GROUP_ID FROM mytable;
DECLARE done BIT DEFAULT 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
DECLARE groupID INT;
read_loop: LOOP
FETCH groupCursor INTO groupID;
IF done THEN
LEAVE read_loop;
ELSE
DELETE FROM mytable
WHERE GROUP_ID = groupID
AND DATETIME < (SELECT MIN(DATETIME) FROM mytable WHERE GROUP_ID=groupID
ORDER BY DATETIME DESC LIMIT 50);
END IF;
END LOOP;
CLOSE groupCursor;
END$$
要调用例程,您需要做的就是:
CALL maintenanceTaskDelete();
【讨论】:
这是比我做过的更高级的 SQL,我有点理解发生了什么,尽管当我把它扔到 MySQL Workbench 中时,所有的 DECLARE 都被突出显示为红色,它会抛出一个错误。在第一行 我刚刚在响应中更新了我的脚本。如果您仍然遇到语法错误,请告诉我。 版本:5.0.77,第一次声明还是报错 您可能需要将上述所有代码放入一个存储过程(MySQL Workbench 中的“例程”)并调用该例程。 即使在例程中它说第一个声明是语法错误【参考方案2】:尝试:
delete from yourtable
where PK in (select pk
from (select
pk,
row_number() over(partition by GROUP_ID order by GROUP_ID, activity_date) as RowNumber
from yourtable
) dt
where RowNumber>50
)
编辑 我刚刚看到这是针对 mysql 而不是 ms sql。 mysql没有row_number()。
【讨论】:
row_number() 未在 MySQL 中定义...如果我没记错那是 MS_SQL @,Alex Angelini,如果可以的话,我会删除这个答案。我不确定我在想什么,MySql
多次出现在这个问题中。以上是关于SQL 维护脚本的主要内容,如果未能解决你的问题,请参考以下文章