SQL: SELECT n% avec des images, (100-n)% sans images

nous avons une database qui stocke les users qui peuvent avoir des photos.

Je suis à la search d'une manière élégante en SQL pour get les résultats suivants: Sélectionnez n users. Parmi ces users, par exemple 60% devraient avoir une image associée et 40% ne devraient pas avoir d'image. Si less de 60% des users ont une image, le résultat doit être rempli avec les users sans image.

Existe-t-il un moyen élégant en SQL sans tirer plusieurs SELECT sur la DB?

Merci beaucoup.

Code laid

SELECT TOP @n * FROM ( //-- We start selecting users who have a picture (ordered by HasPicture) //-- If there is no more users with a picture, this query will fill the //-- remaining rows with users without a picture SELECT TOP 60 PERCENT * FROM tbUser ORDER BY HasPicture DESC UNION //-- This is to make sure that we select at least 40% users without a picture //-- AT LEAST because in the first query it is possible that users without a //-- picture have been selected SELECT TOP 40 PERCENT * FROM tblUser WHERE HasPicture = 0 //-- We need to avoid duplicates because in the first select query we haven't //-- specified HasPicture = 1 (and we didn't want to). AND UserID not IN ( SELECT TOP 60 PERCENT UserID FROM tbUser ORDER BY HavePicture DESC ) ) 

Donc vous fournissez @n, étant le nombre d'users que vous voulez. Vous indiquez @x étant le pourcentage de ces users qui devraient avoir des images.

 select top (@n) * from ( select top (@n * @x / 100) * from users where picture is not null union all select top (@n) * from users where picture is null ) u order by case when picture is not null then 1 else 2 end; 

Donc … vous voulez au plus @n * @x / 100 users qui ont des photos, et le rest doit être des gens qui n'ont pas de photos. Donc je fais un 'union tout' entre mon @ n * @ x / 100 picture-people et assez d'autres pour compléter mon @n. Ensuite, je les sélectionne en arrière, en commandant mon TOP pour m'assurer que je garde les gens qui ont une photo.

Rob

Édité: En fait, ce serait mieux:

 select top (@n) * from ( select top (@n * @x / 100) *, 0 as NoPicture from users where picture is not null union all select top (@n) *, 1 as NoPicture from users where picture is null ) u order by NoPicture; 

… car il supprime l'impact de l'ORDER BY.

 SELECT TOP(n) HasPicture --should be 0 or 1 to allow ORDER FROM Users ORDER BY 1 

Utilisez la case Sélectionner pour ce type d'exigence.