On Tue, 04 Mar 2003 10:43:13 +0100, Jens Vestergaard wrote:
> Hejsa.
> SQL har aldrig været min stærke side...
>
> Problem: Fra en database med 1000 poster skal jeg vælge 50 *tilfældige*, som
> skal fremkomme i tilfældig rækkefølge, når man 'bladrer' igennem dem.
> Løsning: ?
Se her (kommenteret udgave af
http://www.mvps.org/access/queries/qry0011.htm )
Man erklærer følgende funktion i et modul:
'Code courtesy of
'Joe Foster
'************ Code Begin ***********
Function Randomizer () As Integer
Static AlreadyDone As Integer
If AlreadyDone = False Then Randomize : AlreadyDone = True
Randomizer = 0
End Function
'************ Code End *************
Det, som funktionen gør, er, at kalde Randomize, hvis den ikke er blevet
kaldt før. Randomize initialiserer tilfældigtalsgeneratoren, således at
Rnd ikke returnerer den samme værdi som tidligere. Ellers returnerer
funktionen 0 hver gang den kaldes.
For at udtrække f.eks. 100 tilfældige poster, kan man bruge følgende
forespørgsel
SELECT TOP 100 mytable.*
FROM mytable
WHERE Randomizer() = 0
ORDER BY Rnd(IsNull(mytable.question) * 0 + 1)
Da funktionen Randomizer() returnerer 0 hver gang, overholder alle poster
betingelsen Randomizer() = 0. Betingelsen bruges derfor kun til at
initialisere tilfældigtalsgeneratoren én gang.
Umiddelbart virker "ORDER BY" delen også lidt mystisk, da
IsNull(mytable.question) * 0 altid giver 0 ligegyldig om IsNull returnerer
sand eller falsk. Man burde derfor i stedet kunne skrive ORDER BY Rnd(1),
da det er dette kald, der altid forekommer. Men hvis man gør dette
returnerer forespørgselen alle poster i tabellen. Dette er på grund af, at
ORDER BY Rnd(1) ses som en konstant (som er ens for alle poster), og da
prædikatet TOP vælger ikke mellem ens værdier, returneres alle.
IsNull(mytable.question) * 0 + 1 tvinger at resultatet udregnes for alle
poster, derfor bliver Rnd kaldt for alle poster. Da Rnd returnerer en
tilfældig værdi (når argumentet er større end 0), får de enkelte poster en
lige chance for at blive returneret.
--
Mikkel Bundgaard
Student at IT University of Copenhagen
Codito, Ergo Sum