Je sais qu'il y a une tonne de questions sur la recherche et la suppression des valeurs en double dans mySQL
mais ma question est un peu différente:
J'ai une table avec des colonnes comme ID
, Timestamp
et price
. Un script extrait les données d'une autre page Web et les enregistre dans la base de données toutes les 10 secondes. Parfois, les données finissent comme ceci:
| id | timestamp | price | |----|-----------|-------| | 1 | 12:13 | 100 | | 2 | 12:14 | 120 | | 3 | 12:15 | 100 | | 4 | 12:16 | 100 | | 5 | 12:17 | 110 |
Comme vous le voyez, il y a 3 valeurs dupliquées et la suppression du price
avec ID = 4
réduira la table sans endommager l'intégrité des données. Je dois remove continuous duplicated records except the first one
(qui a l' ID
ou l' Timestamp
le plus bas).
Y a-t-il un moyen suffisant de le faire? (il y a environ un million d'enregistrements)
J'ai édité mon script de scraping pour qu'il vérifie le price
double avant de l'ajouter, mais je dois réduire et conserver mes anciennes données.
3 Réponses :
Ma requête est basée sur celle de @Tim Biegeleisen.
-- delete records DELETE FROM yourTable t1 -- where exists an older one with the same price WHERE EXISTS (SELECT 1 FROM yourTable t2 WHERE t2.price = t1.price AND t2.id < t1.id -- but does not exists any between this and the older one AND NOT EXISTS (SELECT 1 FROM yourTable t3 WHERE t1.price <> t3.price AND t3.id > t2.id AND t3 < t1.id));
Il supprime les enregistrements où il en existe un plus ancien avec le même prix mais il n'existe pas de différence entre
Il pourrait être vérifié par la colonne d' timestamp
si la colonne id
n'est pas numérique et croissante.
Merci pour l'excellente réponse mais j'ai du mal à l'exécuter. Cela me donne l'erreur 1064.
L'erreur a été causée par un mauvais commentaire (espace manquant)
Je ne fais que regrouper en fonction du prix et filtrer un seul enregistrement par groupe. L'identifiant le plus bas s'affiche. J'espère que ce qui suit vous aidera.
select id,timestamp,price from yourTable group by price having count(price)>0;
Depuis MySQL 8.0, vous pouvez utiliser la fonction de fenêtre LAG () de la manière suivante:
delete tbl.* from tbl join ( -- use lag(price) for get value from previous row select id, lag(price) over (order by id) price from tbl ) l -- join rows with same previous price witch will be deleted on tbl.id = l.id and tbl.price = l.price;
Ajout d'une explication