如何遍历结果并删除除最新项目之外的所有内容?

时间:2011-12-07 18:42:25

标签: mysql sql sql-delete

我有一个有玩家和活动的数据库。一名球员有很多赛事。活动有创建日期。

我们希望清理我需要编写SQL(使用MySQL)的数据库,每个玩家都会删除除最新事件之外的所有事件。

那么如何在SQL中进行这种循环和自定义删除:

select all PLAYERS from PLAYER
for each PLAYER
delete all EVENTS except where EVENT.creationDate is the newest one

非常感谢任何帮助!

更多细节

PLAYER表有PLAYER_ID varchar(100)

EVENT表有EVENT_ID bigint,PLAYER_ID varchar(100),CREATED_AT(bigint)

4 个答案:

答案 0 :(得分:4)

MySQL支持多表删除作为SQL的扩展。您可以在不使用子查询的情况下进行连接。

DELETE e1 
FROM Players p 
INNER JOIN Events e1 ON p.player_id = e1.player_id
INNER JOIN Events e2 ON p.player_id = e2.player_id
WHERE e1.event_id < e2.event_id;

如果另一行e1存在且event_id较高且同一玩家,则我们要删除行e2。当然,给定玩家的最新事件永远不能通过e1的条件。

我假设event_id随着creationDate的增加而增加,选择它会更好,因为它永远不会产生平局。

答案 1 :(得分:1)

每个部分的

SELECT Events.creationDate FROM Events WHERE Events.player ==(每个玩家)ORDER BY DESC LIMIT 1; //为您提供第一个活动

将它放在类似DateLastEvent的var

DELETE Events WHERE Events.creationDate&lt; DateLastEvent:

//除非严格按照相同的日期/时间删除所有其他

答案 2 :(得分:1)

您可能希望执行delete的多表语法,并结合子查询来创建引用表,您可以在其中检查最新的creationDate:

DELETE FROM `events` 
  USING `events` 
    INNER JOIN (
      SELECT playerId, MAX(creationDate) AS `maxCreationDate` 
      FROM `events` GROUP BY playerId) AS `referenceTable` 
    USING (`playerID`) 
  WHERE `events`.`playerId` = `referenceTable`.`playerId` 
    AND `events`.`creationDate` != `referenceTable`.`maxCreationDate`;

使用这些表进行测试:

mysql> SELECT * FROM players;
+----------+------------+
| playerId | playerName |
+----------+------------+
|        1 | Andy       |
|        2 | Buddy      |
+----------+------------+
2 rows in set (0.00 sec)

mysql> SELECT * FROM events;
+---------+----------+---------------------+
| eventId | playerId | creationDate        |
+---------+----------+---------------------+
|       3 |        1 | 2011-12-06 01:49:58 |
|       1 |        1 | 2011-12-07 01:49:20 |
|       2 |        1 | 2011-12-08 01:50:03 |
|       1 |        2 | 2011-12-07 01:50:06 |
|       2 |        2 | 2011-12-08 01:50:00 |
+---------+----------+---------------------+
5 rows in set (0.00 sec)

结果看起来不错。

mysql> DELETE FROM `events` 
    -> USING `events` 
    -> INNER JOIN (
    -> SELECT playerId, MAX(creationDate) AS `maxCreationDate` 
    -> FROM `events` GROUP BY playerId
    -> ) AS `referenceTable` 
    -> USING (`playerID`) 
    -> WHERE `events`.`playerId` = `referenceTable`.`playerId` 
    -> AND `events`.`creationDate` != `referenceTable`.`maxCreationDate`;
Query OK, 3 rows affected (0.03 sec)

mysql> SELECT * FROM events;
+---------+----------+---------------------+
| eventId | playerId | creationDate        |
+---------+----------+---------------------+
|       2 |        1 | 2011-12-08 01:50:03 |
|       2 |        2 | 2011-12-08 01:50:00 |
+---------+----------+---------------------+
2 rows in set (0.00 sec)

答案 3 :(得分:0)

  

从event_id不在的玩家中删除      (从event_date中选择event_id(通过player_id从玩家组中选择min(event_date)))

这是一个简单的查询,也可以。