2009-08-06 4 views
3

J'ai une grande table avec 300 000 enregistrements. Cette table a une valeur entière appelée "vitesse" et sa valeur est comprise entre 0 et 100. Dans les premiers enregistrements, la valeur est 0 et je souhaite la supprimer. Je veux enlever de la requête, les enregistrements où le champ de vitesse se répète plus de 10 fois. Par exemple:mySQL pour récupérer les enregistrements qui répètent une valeur dans l'ordre

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 5 10 12 13 15 20 30 20 15 10 8 5 2 1 0 0 0 0 4 5 10 20 ...

[------- supprimer ce -----------] ........................ ............................................... [- -------] < - ne pas enlever cette

Merci

+0

Comment garantissez-vous "premier"? les lignes ne sont PAS commandées. – colithium

+0

Répète en blocs de 10 lignes consécutives (une après l'autre), ou la 11ème rangée + (s)? –

Répondre

0

Je venais de déchirer les dossiers de manière séquentielle, avec une fenêtre de taille variable qui monte et descend à comprendre des valeurs identiques. Chaque fois que la taille est> = 10 lorsque la valeur change, supprimez les lignes à l'aide des clés primaires.

Vous pouvez mettre BEGIN TRAN et COMMIT TRAN au début et à la fin des instructions DELETE pour rendre les choses raisonnablement efficaces.

+0

Remarque: Étant donné que l'opération dépend de l'ordre des enregistrements, il ne s'agit pas vraiment d'un problème lié à un ensemble. Donc, l'utilisation de SQL va être gênant. Probablement mieux d'utiliser votre langage procédural et de le regarder comme une liste ordonnée. – dkretz

3

La méthode la plus simple consiste à utiliser une boucle. Vous pouvez écrire une procédure stockée qui itère dans les enregistrements, ou vous pouvez le faire en dehors de la base de données. Je le ferais comme ça si cela doit être fait une fois. S'il s'agit d'un processus continu, il est préférable de s'assurer que les données supplémentaires ne sont tout simplement pas insérées dans la base de données en premier lieu.

Quoi qu'il en soit, si vous insistez pour le faire cela dans SQL pur, sans procédures stockées avec des boucles, vous pouvez utiliser une requête comme ceci:

set @groupnum=0; 

select 
    GroupNum, 
    count(*) as RecsInGroup 
from 
(
    select 
     t1.id as Id, 
     t1.velocity as velocity1, 
     t2.velocity as velocity2, 
     if(t1.velocity<>t2.velocity,@groupnum:[email protected]+1,@groupnum) as GroupNum 
    from 
     VelocityTable as t1 
    join 
     VelocityTable as t2 
    on 
     t1.id=t2.id-1 
) as groups 
group by 
    GroupNum 
having RecsInGroup>10 

Qu'est-ce qui se passe ici?

Étape 1

La requête interne sélectionne simplement tous les enregistrements de votre table, mais divise les données en groupes séquentiels.

Ainsi, en utilisant votre exemple, il le fait:

velocity : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 5 10 12 13 15 20 30 20 15 10 8 5 2 1 0 0 0 0 4 5 10 20 
Groupnum : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 18 18 18 19 20 21 22 

Il le fait en se joignant à la table elle-même, en reliant les enregistrements suivants dans le tableau. Chaque fois que la vitesse gauche et droite sont différentes, le GroupNum est augmenté. Sinon, il reste inchangé.

Etape 2

Le résultat si la requête est enveloppé dans une requête externe, et regroupées par groupnum. Encore une fois, en utilisant votre exemple, il entraînerait ceci:

GroupNum,RecsInGroup 
0,15 // !! 
1,1 
2,1 
3,1 
4,1 
5,1 
6,1 
7,1 
8,1 
9,1 
10,1 
11,1 
12,1 
13,1 
14,1 
15,1 
16,1 
17,1 
18,4 // !! 
19,1 
20,1 
21,1 

En ajoutant la clause having RecsInGroup>10, le résultat devient ceci:

GroupNum,RecsInGroup 
0,15 

Maintenant, avec cette liste de groupnum, vous pouvez le supprimer des enregistrements.

Étape 3

Avec la requête ci-dessus vous avez:

  1. Une liste de tous vos enregistrements, avec une colonne ajoutée GroupNum.
  2. La liste des numéros de groupe qui doivent être supprimés.

La suppression des enregistrements devrait être facile à ce stade.

0

merci beaucoup. Je suis la plupart du temps là-bas, mais je l'ai essayé avec une vue mySQL comme source de table et cela ne fonctionne pas (table inconnue xxx). Je ne peux pas utiliser toute la table, car il y a plus de 19 millions de disques, j'ai juste besoin de l'enregistrement d'une journée spécifique, d'une plaque d'immatriculation et d'une ville.

Questions connexes