#1 Fri 03 November 2006 19:30
échantillon au hasard
La question est de retirer d'une table un certain nombre d'enregistrements au hasard. J'ai testé plusieurs suggestions mais il y en a une qui me bloque. La proposition originale était la suivante
select Rnd(1) "Hasard", ID from ma_table order by 1 into triée
puis de se servir de triée pour retirer les N enregistrements voulus. Le problème que j'ai rencontré (Mi 7.0) est que le tri ne se fait pas. Comme référence, j'ai mis à jour une colonne de ma_table avec Rnd(1) puis fait le tri; résultats parfaits.
J'ai ensuite testé deux sélections successives
select Rnd(1) "Hasard", ID from ma_table into tri1
select * from tri1 order by 1 into tri2
et encore une fois le tri ne se fait pas. Ma question : est-il possible que Rnd() régénère des valeurs alors que le tri est en cours? Ne faut-il pas que les valeurs obtenues soient codées en dur (comme après un update) pour pouvoir être triées?
Hors ligne
#2 Sat 04 November 2006 14:21
Re: échantillon au hasard
J'ai eu une réponse partielle mais qui donne une idée de la nature du problème. Il semble que Rnd() reste collé comme définition de la colonne au moins dans les tables provisoires (les résultats de sélection par exemple) et que chaque manipulation de la colonne relance la création de nouvelles valeurs. Ce n'est que dans les tables permanentes pour lesquelles les valeurs de Rnd() sont assignées cas par cas que l'origine des valeurs (la fonction même) est oubliée.
Je ferais un parallèle avec excel: une cellule peut être définie par une valeur ou une formule. Dans MI une colonne définie par Rnd() reste une formule (colonne temporaire), l'assignation de Rnd() aux cellules d'une colonne permanente donne des valeurs.
Pour "fixer" le contenu d'une colonne temporaire définie par Rnd(), il faut sauvegarder cette table en table permanente, puis l'ouvrir pour travailler dessus (par exemple trier dans l'ordre des valeurs de la colonne rnd). Il faut remarquer au passage que les valeurs de la colonne temporaire ont été changées lors de la sauvegarde de la table provisoire. Il ne faut donc pas se fier aux valeurs obtenues en première lecture de cette table. La table permanente ne contient plus les mêmes valeurs mais elles sont encore produites par rnd() donc théoriquement au hasard.
Deux conclusions s'imposent
1- ne pas utiliser la procédure de sélection avec création de colonne temporaire par Rnd(). Cela oblige à créer une table permanente supplémentaire et à l'ouvrir. Procéder plutôt par l'ajout d'une colonne float dans la table originale (ou une copie) et sa mise à jour avec rnd()
2 - se questionner sur quelles autres fonctions auraient un tel comportement facheux. les fonctions "géographiques" (surface par ex.) étant appliquées sur des objets spécifiques (dans le même enregistrement) ne devraient pas poser de problème. Mais les autres? Quelles autres?
Hors ligne