【问题标题】:SQL Maintenance ScriptSQL 维护脚本
【发布时间】: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

谢谢

【问题讨论】:

    标签: mysql sql maintenance


    【解决方案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 多次出现在这个问题中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-01
    • 2014-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-04
    相关资源
    最近更新 更多