2014-04-29 4 views
1

Je dois extraire une ligne aléatoire d'un ensemble de lignes dans ma base de données SQL Server.Ligne aléatoire Microsoft SQL Server

Ceci est la requête que je dirige actuellement:

SELECT TOP 1 * 
FROM 
    (SELECT * FROM Flowers WHERE Color = 'Red') a 
ORDER BY NEWID() 

Pour autant que je comprends, cela devrait aller chercher toutes les fleurs avec la couleur rouge. Et puis de l'un d'eux sélectionnez une fleur aléatoire. Mais il me semble qu'il ne sélectionne que d'un assez faible nombre d'entrées, car je vois souvent le même couple de fleurs. Maintenant, je me demande si ma requête ne fonctionne pas aussi bien que je le pensais, est-ce que quelqu'un voit un problème avec elle?

+1

Eh bien, combien de lignes fait le SELECT 'FROM Flowers WHERE Color = "Red" 'return ?. (En outre, vous devriez utiliser 'WHERE Color = 'Red'', avec des guillemets simples) – Lamak

+0

Voici un bon lien sur la sélection de lignes aléatoires en sql - http://www.petefreitag.com/item/466.cfm –

+1

Comment beaucoup de fleurs rouges sont là et à quelle fréquence voyez-vous des doublons? Vous devez vraiment faire une analyse statistique pour déterminer le caractère aléatoire des résultats. – AaronLS

Répondre

1

Vous n'avez pas besoin d'utiliser une sous-requête que vous pouvez simplement sélectionner directement dans la table en utilisant la clause where et l'ordre de newid(). Quelque chose comme ....

SELECT TOP 1 * 
FROM Flowers 
WHERE Color = 'Red' 
ORDER BY NEWID() 
+0

Et pourquoi cela retournerait-il un nombre différent de lignes que ce que op utilise, ou un résultat différent ?, est fondamentalement la même requête – Lamak

+0

Il ne reviendrait pas un autre nombre de lignes, mais ici le serveur sql ne doit pas retourner toutes les lignes où color = 'Red' seulement pour renvoyer une ligne de ce jeu de résultats. ce sera certainement le même traitement de données inutile. –

+1

L'optimiseur utilisera probablement le même plan pour votre requête et celle de votre opérateur. Quelque chose d'aussi trivial qu'une «table dérivée» ne va pas confondre l'optimiseur – Lamak

1

Le ORDER BY NEWID() est connu pour ne pas randomiser aussi bien. Vous obtiendrez un bien meilleur résultat avec ORDER BY CHECKSUM(NEWID()).

+2

Pouvez-vous expliquer '" 'ORDER BY NEWID()' est connu pour ne pas bien randomiser "? Quels seraient les problèmes? –

+2

Des liens pour prouver cette hypothèse? – Lamak

+1

@Lamak Itzik le mentionne [ici] (http://sqlmag.com/t-sql/perils-t-sql-randomization) pour certains systèmes d'exploitation. 2008 a introduit CRYPT_GEN_RANDOM quand même. –