1
votes

Supprimez les valeurs dupliquées en continu avec différents ID dans MySQL

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.


0 commentaires

3 Réponses :


1
votes

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.


2 commentaires

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)



1
votes

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;


0 commentaires

1
votes

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;

violon


1 commentaires

Ajout d'une explication