我有一张表格,表格如下
GROUP_ID | FOO | BAR | DATETIME
我有一个cron,每晚更新这张桌子。但是,我希望在我的脚本结束时运行一个sql命令,该命令将确保每个group_id的50个最新行都存在,而其他任何行都被删除。
例如:如果有60行且GROUP_ID = 1,我希望此次运行后只剩下最近的50行。如果GROUP_ID = 2只有20行,则将它们全部保留。
这只能在SQL中实现,还是我需要在PHP中实现这一点(我的大多数应用程序都是用它构建的)
我正在运行MySQL
由于
答案 0 :(得分: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 ;
UPDATE 根据下面的讨论,这是一个存储过程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();
答案 1 :(得分:0)
尝试:
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()。