Как просмотреть результаты и удалить все, кроме самого нового элемента? - PullRequest
2 голосов
/ 07 декабря 2011

У меня есть БД с игроками и событиями. Один игрок имеет много событий. Событие имеет дату создания.

Мы хотим очистить БД. Мне нужно написать 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 ]

4 голосов
/ 07 декабря 2011

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, если существует другая строка e2 с более высоким event_id и тем же игроком.Естественно, самое последнее событие для данного игрока никогда не может пройти условие для e1.

Я предполагаю, что event_id увеличивается с увеличением creationDate, и лучше выбрать это, так как это никогда не приведет к ничьей.

1 голос
/ 07 декабря 2011

Возможно, вы захотите использовать синтаксис удаления нескольких таблиц в сочетании с подзапросом для создания справочной таблицы, в которой вы можете проверить новейшую дату создания:

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)
1 голос
/ 07 декабря 2011

в каждом разделе:

SELECT Events.creationDate FROM Events WHERE Events.player == (каждый игрок) ORDER BY DESC LIMIT 1; // получить первое событие

Поместите его в переменную типа DateLastEvent или около того

УДАЛИТЬ События, ГДЕ Events.creationDate

// за исключением случаев, когда строго в ту же дату / время будут удалены все остальные

0 голосов
/ 07 декабря 2011

Удалить из игроков, в которых event_id отсутствует (выберите event_id из игроков, в которых event_date (выберите min (event_date) из группы игроков по player_id))

Это простой запрос, которыйтакже работает.

...