9
votes

Comment supprimer au hasard 20% des rangées dans une table SQLite

Bon après-midi, nous nous demandions comment supprimer de manière aléatoire 20% des rangées dans une table SQLite avec 15 000 rangées. Nous avons remarqué que cette question a été résolue dans un débordement de pile à l'aide de SQL Server Sélectionnez N aléatoire rangées de la table SQL Server . Mais le script SQL Server n'apparaît pas fonctionner correctement dans SQLite. Comment pouvons-nous convertir le script SQL Server en un script équivalent SQLite? Merci.


1 commentaires

Quel est le problème avec Réponse de Kevin Peno ?


4 Réponses :


5
votes

pas tout à fait "aléatoire" - mais si vous avez une colonne d'identité sur la table, vous pouvez supprimer de MyTable où ID% 5 = 0 qui devrait statistiquement la suppression de manière statistique à une cinquième des rangées .


8 commentaires

@Will a, merci pour votre réponse. Je viens d'accepter votre réponse. La seule colonne d'identité que nous avons dans notre table est la colonne de RowID implicite. Puissions-nous substituer Rowid for ID dans votre réponse? Merci pour votre suggestion.


@Frank - mon plaisir, monsieur. Oui, Rowid ira bien.


@Frank: Vous pouvez utiliser Rowid . Vous pouvez également utiliser où aléatoire ()% 5 = 0 .


@Willa, merci de répondre. Je vais l'essayer bientôt et vous faire connaître nos résultats.


@Nick Dandoulakis, merci de répondre. Je vais l'essayer dès que je fais une copie de ma base de données SQLite. Merci de votre aide.


@Willa, nous avons essayé votre réponse. Cela fonctionne correctement. Je me demandais comment nous pourrions faire contigu les Rowids sur la suppression aléatoire. Merci de votre aide.


@Nick Dandoulakis, j'ai essayé votre réponse où aléatoire ()% 5 = 0. C'est un succès. Nous nous demandions si nous pouvions faire la contiguë de la Rowid après la suppression des lacunes de StateMeNtNt dans la table modifiée. Merci pour votre aide.


simple mais génial



4
votes

Essayez:

DELETE FROM TABLE 
WHERE ROWID IN (SELECT ROWID FROM TABLE ORDER BY RANDOM() LIMIT 3000) 


4 commentaires

@ user589993, merci pour votre réponse. Je viens d'accepter votre réponse. Nous n'avons pas de colonne d'identité dans notre table SQLite. Puissions-nous utiliser Rowid au lieu de ID? Merci de votre aide.


Oui, Rowid fonctionnera de la même manière, et il semble que vous ayez accepté l'une des autres solutions.


@ user589993, merci pour votre réponse. Je vais essayer tout de suite et vous laissera savoir nos résultats.


@ user589993, j'ai essayé votre réponse. Il court rapidement. J'étais juste curieux si nous pouvions faire contigu des rangées dans la table modifiée après la suppression aléatoire. Merci de votre aide.



2
votes

SQLite - L'ordre by Rand () fournit un indice. Ainsi, cela peut fonctionner? XXX


4 commentaires

Merci pour votre réponse. Je viens d'accepter votre réponse. Puissions-nous substituer Rowid for ID dans votre réponse. Merci pour votre aide.


Je suis ton essayé ta réponse. Cela fonctionne correctement. J'ai remarqué qu'il y a maintenant des lacunes dans Rowid. Est-il possible de faire de la contiguë aux rajusts? Merci de votre aide.


@Frank, afin de faire de Rowid à nouveau contiguë, vous devez copier les données sur une table TEMP, tronquer la table actuelle, puis réinsérez les anciennes données. Cependant, je suis d'accord avec l'autre commentaire de ne pas avoir besoin de m'en soucier.


Pour moi, cela ressemble à la réponse uniquement avec un résultat exact ou ai-je négligé quelque chose? BTW: CAST n'est pas nécessaire (au moins pour la version 3.21.0).



5
votes

Alternativement, puisque la fonction aléatoire () dans SQLite retourne un entier 64 bits signé, nous pouvons calculer un point dans cet espace comme (2 ^ 63) * 0,6. Les entiers signés supérieurs à ce que cela ne représentera 40% de l'ensemble des entiers positifs signés 64 bits, donc 20% de l'ensemble de l'ensemble.

tronquer sur l'entier ci-dessous, il s'agit de 5534023222112865484. P>

Vous devrait être capable d'obtenir 20% de vos lignes avec un simple: p> xxx pré>

ou dans votre cas, car vous souhaitez supprimer beaucoup: P>

   DELETE FROM table WHERE random() > 5534023222112865485


4 commentaires

Merci pour votre réponse. J'ai juste essayé d'accepter votre réponse. Une fois que nous avons exécuté de la table de la table où aléatoire ()> 55340232222112865485, il y aura des lacunes dans les fuseaux dans la table. Savez-vous quelles instructions SQLite à courir pour fermer les lacunes de Rowid? Merci.


En tant que bonne pratique générale, vous ne devez pas vous soucier des valeurs réelles de Rowid, et s'il peut y avoir des lacunes dans la séquence. Pour diverses raisons, la base de données peut se retrouver avec des lacunes dans la séquence du cours normal d'utilisation dans tous les cas. Par exemple quand vous commencez; INSÉRER; INSÉRER; S'ENGAGER; dans un fil pendant que vous commencez; INSÉRER; RETOUR EN ARRIERE; Dans un autre fil, vous pourriez vous retrouver avec une lacune dans Rowid.


En outre, comme une personne indique dans un commentaire ci-dessous, en utilisant où (aléatoire ()% 5) = 0 est vraiment une meilleure solution à la mine, car elle ne nécessite pas le calcul de la taille d'un Int signé 64 bits, et il n'a pas le potentiel d'être du matériel / une version dépendante.


Merci pour vos réponses. Votre commentaire sur les lacunes dans le Rowid est très utile. Votre deuxième commentaire sur l'endroit où (aléatoire ()% 5) nous est également très utile, en particulier depuis que nous voulons que notre solution soit indépendante, merci.