/ Forside / Teknologi / Udvikling / ASP / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
ASP
#NavnPoint
smorch 9259
Harlekin 1866
molokyle 1040
Steffanst.. 758
gandalf 657
smilly 564
gibson 560
cumano 530
MouseKeep.. 480
10  Random 410
SELECT RANDOM
Fra : Jacob ..


Dato : 08-03-04 10:31

Hvorledes kan jeg lave en SELECT RANDOM af 3 rækker i min
ACCESS-DB?



--
Vil du lære at kode HTML, XHTML, CSS, SSI eller ASP?
- Pædagogiske tutorials på dansk
- Kom godt i gang med koderne
KLIK HER! => http://www.html.dk/tutorials

 
 
Torben Brandt (08-03-2004)
Kommentar
Fra : Torben Brandt


Dato : 08-03-04 12:35

Jacob .. skrev:
> Hvorledes kan jeg lave en SELECT RANDOM af 3 rækker i min
> ACCESS-DB?

Se evt på <URL:http://actuar.dk/torben/show.asp?id=randomrecords> som
dog ikke er hensigtsmæssig, hvis der er for mange poster i tabellen...

mvh Torben


Michael Zedeler (08-03-2004)
Kommentar
Fra : Michael Zedeler


Dato : 08-03-04 15:14

Torben Brandt wrote:
> Jacob .. skrev:
>
>> Hvorledes kan jeg lave en SELECT RANDOM af 3 rækker i min
>> ACCESS-DB?

> Se evt på <URL:http://actuar.dk/torben/show.asp?id=randomrecords> som
> dog ikke er hensigtsmæssig, hvis der er for mange poster i tabellen...

Den løning synes jeg ikke er specielt smart. Der er mange problemer med den.

En helt anden metode er følgende:

Feltet id er et heltalsfelt med unikke nøgler for tabellen.
Dernæst genererer man ét tilfældigt tal og bruger det i følgende sætning:

SELECT TOP 3 *, id * <tilfældigt tal> * <primtal_1> % <primtal_2> FROM tabel

De to primtal skal vælges så hjøt som muligt. primtal_1 skal dog helst
være en del større end primtal_1. I en konkret applikation har jeg valgt:

primtal_1 := 18409199
primtal_2 := 99989

Dette giver en pæn sortering så længe at man ikke har væsentligt flere
poster end 99989.

Fordele ift. den metode som du har linket til:

* Metoden virker for et meget stort antal poster.
* Man skal næsten ikke lave nogen forbehandling af data.
* Metoden er mere tilfældig.
* Der er mindre trafik til databasen.
* Der er intet subselect eller left join hvilket gør forespørgslen
MEGET hurtigere.

Mvh. Michael.


Jens Gyldenkærne Cla~ (08-03-2004)
Kommentar
Fra : Jens Gyldenkærne Cla~


Dato : 08-03-04 15:42

Michael Zedeler skrev:

> Feltet id er et heltalsfelt med unikke nøgler for tabellen.
> Dernæst genererer man ét tilfældigt tal

I hvilket område? 0-1, 1-1000, 1-[max ID]?


> SELECT TOP 3 *, id * <tilfældigt tal> * <primtal_1> %
> <primtal_2> FROM tabel

Hvilken Access-version benytter du? "%" er ikke en gyldig operator
i Access 2000 - jeg ved ikke om det er lavet om i nyere versioner.

Man kan skrive "mod" hvis meningen er modulus - men det ændrer ikke
ved de poster der trækkes ud.

Forklar gerne hvordan (og hvorfor) din metode virker - og i hvilke
databaser den virker.


> primtal_1 := 18409199
> primtal_2 := 99989

Jeg har prøvet med følgende sætning - der bare returnerer de tre
første poster:

SELECT TOP 3 *, id*42*18409199 Mod 99989
FROM tabelnavn;
--
Jens Gyldenkærne Clausen
Svar venligst under det du citerer, og citer kun det der er
nødvendigt for at forstå dit svar i sammenhængen. Se hvorfor og
hvordan på http://usenet.dk/netikette/citatteknik.html

Michael Zedeler (08-03-2004)
Kommentar
Fra : Michael Zedeler


Dato : 08-03-04 15:59

Jens Gyldenkærne Clausen wrote:
> Michael Zedeler skrev:
>
>>Feltet id er et heltalsfelt med unikke nøgler for tabellen.
>>Dernæst genererer man ét tilfældigt tal
>
> I hvilket område? 0-1, 1-1000, 1-[max ID]?

Heltal i intervallet [1; MAX_INT/(18409199*MAX_RAND)]

>>SELECT TOP 3 *, id * <tilfældigt tal> * <primtal_1> %
>><primtal_2> FROM tabel
>
> Hvilken Access-version benytter du? "%" er ikke en gyldig operator
> i Access 2000 - jeg ved ikke om det er lavet om i nyere versioner.

% er modulo-operatoren.

> Man kan skrive "mod" hvis meningen er modulus - men det ændrer ikke
> ved de poster der trækkes ud.

Jeps.

> Forklar gerne hvordan (og hvorfor) din metode virker - og i hvilke
> databaser den virker.

Den virker i alle databaser der kan regne på store heltal hvor
modulo-operatoren er tilgængelig.

Metoden virker fordi at de genererede tal er pseudotilfældige.

>>primtal_1 := 18409199
>>primtal_2 := 99989

> Jeg har prøvet med følgende sætning - der bare returnerer de tre
> første poster:
>
> SELECT TOP 3 *, id*42*18409199 Mod 99989
> FROM tabelnavn;

Jeg glemte en *MEGET VIGTIG* ting:

SELECT TOP 3 *, id*42*18409199 Mod 99989 ordering FROM tabelnavn ORDER
BY ordering;

(ORDER BY-tingen.)

Mvh. Michael.


Jens Gyldenkærne Cla~ (08-03-2004)
Kommentar
Fra : Jens Gyldenkærne Cla~


Dato : 08-03-04 16:14

Michael Zedeler skrev:

> Heltal i intervallet [1; MAX_INT/(18409199*MAX_RAND)]

Hvad er MAX_RAND?
`

>> Hvilken Access-version benytter du? "%" er ikke en gyldig
>> operator i Access 2000 - jeg ved ikke om det er lavet om i
>> nyere versioner.
>
> % er modulo-operatoren.

Jeg spørger lige igen - hvilken Accces-version benytter du?
(spørgsmål drejer sig om random-poster i Access).


> Den virker i alle databaser der kan regne på store heltal hvor
> modulo-operatoren er tilgængelig.

Jeg kan ikke få det til at virke i Access 2000.



> Jeg glemte en *MEGET VIGTIG* ting:
>
> SELECT TOP 3 *, id*42*18409199 Mod 99989 ordering FROM
> tabelnavn ORDER BY ordering;

"Ordering"? I Access 2000 får jeg "Indtast parameterværdi
(ordering)" - I MSSQL 2000 får jeg "Invalid column name
'ordering'."

Jeg har aldrig hørt om et "ordering" keyword - og google ser heller
ikke ud til at have noget om det.

Vil du ikke godt fortælle hvilke databaser det virker i?

Jeg sætter opfølgning til databasegruppen - debatten her er ikke
relevant for asp-gruppen.

FUT: <news:dk.edb.database>
Om FUT og X-FUT: <http://www.usenet.dk/ord/lokal.html#fut>

--
Jens Gyldenkærne Clausen
Svar venligst under det du citerer, og citer kun det der er
nødvendigt for at forstå dit svar i sammenhængen. Se hvorfor og
hvordan på http://usenet.dk/netikette/citatteknik.html

Michael Zedeler (08-03-2004)
Kommentar
Fra : Michael Zedeler


Dato : 08-03-04 16:31

Jens Gyldenkærne Clausen wrote:
> Michael Zedeler skrev:
>
>>Heltal i intervallet [1; MAX_INT/(18409199*MAX_RAND)]
>
> Hvad er MAX_RAND?

Det højeste tal man får spyttet ud når man genererer sit tilfældige tal.
Nogle platforme giver mulighed for at man selv kan angive en øvre grænse.

>>>Hvilken Access-version benytter du? "%" er ikke en gyldig
>>>operator i Access 2000 - jeg ved ikke om det er lavet om i
>>>nyere versioner.
>>
>>% er modulo-operatoren.
>
> Jeg spørger lige igen - hvilken Accces-version benytter du?
> (spørgsmål drejer sig om random-poster i Access).

Jeg bruger ikke Access, men kan så godt som garantere at det virker i
Access. Er det et problem?

>>Den virker i alle databaser der kan regne på store heltal hvor
>>modulo-operatoren er tilgængelig.
>
> Jeg kan ikke få det til at virke i Access 2000.

Jeg har lige checket det i Access. Grunden til at det ikke virker er at
den ikke kan håndtere så store tal. Jeg ved ikke hvor store tal den kan
håndtere, så det må du checke selv. Hvis jeg hælder disse primtal ind,
virker det:

100003 og 10003

Kig selv på www.prime-numbers.org for at finde nogle rare primtal.

>>Jeg glemte en *MEGET VIGTIG* ting:
>>
>>SELECT TOP 3 *, id*42*18409199 Mod 99989 ordering FROM
>>tabelnavn ORDER BY ordering;
>
> "Ordering"? I Access 2000 får jeg "Indtast parameterværdi
> (ordering)" - I MSSQL 2000 får jeg "Invalid column name
> 'ordering'."

SELECT TOP 3 *, id*42*18409199 Mod 99989 AS ordering FROM
tabelnavn ORDER BY ordering;

Nogle databaser tillader at man udelader AS - det gør Access
tilsyneladende ikke.

> Vil du ikke godt fortælle hvilke databaser det virker i?

Alle SQL-kompatible databaser.

Hvem har egentlig pisset på din sukkermad? Det jeg skriver bruger et
almindeligt princip for generering af pseudotilfældige tal. At der er
nogle fejl er selvfølgelig beklageligt, men de fejl som jeg skrev i det
oprindelige indlæg er nemme at rette op på hvis man ellers forstår den
undeliggende mening.

Dertil er metoden stadigvæk langt bedre end et outer join i et subselect
med tredobbelt skrue - for slet ikke at tale om at mange poster aldrig
ville blive vist med den oprindeligt foreslåede metode.

Mvh. Michael.


Torben Brandt (08-03-2004)
Kommentar
Fra : Torben Brandt


Dato : 08-03-04 16:53

Michael Zedeler skrev:
> Dertil er metoden stadigvæk langt bedre end et outer join i et subselect
> med tredobbelt skrue - for slet ikke at tale om at mange poster aldrig
> ville blive vist med den oprindeligt foreslåede metode.

Kan du give et eksempel, hvor nogle poster ikke har mulighed for at
blive udtrukket ?

/Torben


Jens Gyldenkærne Cla~ (08-03-2004)
Kommentar
Fra : Jens Gyldenkærne Cla~


Dato : 08-03-04 16:23

Michael Zedeler skrev:

> SELECT TOP 3 *, id*42*18409199 Mod 99989 ordering FROM
> tabelnavn ORDER BY ordering;

Jeg overså det første ordering herover - så glem mine kommentarer
om ordering som keyword. Til gengæld mangler der stadig et "as" - i
hvert fald hvis Access/MSSQL skal forstå alias-kommandoen.

Access 2000 kan desuden ikke håndtere henvisninger til alias-felter
i order by-linjen.

Hvis jeg skriver:

SELECT TOP 3 *, id*2*18409199 Mod 99989 as ordering
FROM tabel ORDER BY id*5*(18409199 Mod 99989 )

- så virker sætningen, men det er hele tiden de tre første poster
der hentes.

Hvis jeg fjerner parantesen, så får jeg en overløbsfejl.

Krydspostet til 2 grupper, opfølgning (FUT) til:
<news:dk.edb.database>
Om FUT og X-FUT: <http://www.usenet.dk/ord/lokal.html#fut>

--
Jens Gyldenkærne Clausen
Svar venligst under det du citerer, og citer kun det der er
nødvendigt for at forstå dit svar i sammenhængen. Se hvorfor og
hvordan på http://usenet.dk/netikette/citatteknik.html

Michael Zedeler (08-03-2004)
Kommentar
Fra : Michael Zedeler


Dato : 08-03-04 16:43

Jens Gyldenkærne Clausen wrote:

> Michael Zedeler skrev:
> [klip]
>
> Access 2000 kan desuden ikke håndtere henvisninger til alias-felter
> i order by-linjen.
>
> Hvis jeg skriver:
>
> SELECT TOP 3 *, id*2*18409199 Mod 99989 as ordering
> FROM tabel ORDER BY id*5*(18409199 Mod 99989 )
>
> - så virker sætningen, men det er hele tiden de tre første poster
> der hentes.

> Hvis jeg fjerner parantesen, så får jeg en overløbsfejl.

Det er fordi at du har anbragt parantesen som du har. Prøv med nogle
mindre primtal og husk at generere et nyt tilfældigt tal hver gang du
kører forespørgslen. Det burde virke.

M.


Torben Brandt (08-03-2004)
Kommentar
Fra : Torben Brandt


Dato : 08-03-04 16:50

Michael Zedeler skrev:
> Torben Brandt wrote:
>> Jacob .. skrev:
>>
>>> Hvorledes kan jeg lave en SELECT RANDOM af 3 rækker i min
>>> ACCESS-DB?

Bemærk her at vi snakker om MS Access.

>> Se evt på <URL:http://actuar.dk/torben/show.asp?id=randomrecords> som
>> dog ikke er hensigtsmæssig, hvis der er for mange poster i tabellen...
>
> En helt anden metode er følgende:
>
> Feltet id er et heltalsfelt med unikke nøgler for tabellen.
> Dernæst genererer man ét tilfældigt tal og bruger det i følgende sætning:
>
> SELECT TOP 3 *, id * <tilfældigt tal> * <primtal_1> % <primtal_2> FROM
> tabel
>
> De to primtal skal vælges så hjøt som muligt. primtal_1 skal dog helst
> være en del større end primtal_1. I en konkret applikation har jeg valgt:
>
> primtal_1 := 18409199
> primtal_2 := 99989
>
> Dette giver en pæn sortering så længe at man ikke har væsentligt flere
> poster end 99989.
>
> Fordele ift. den metode som du har linket til:
>
> * Metoden virker for et meget stort antal poster.

Som jeg også indrømmede fra starten

> * Man skal næsten ikke lave nogen forbehandling af data.

I dit indlæg fra 15.58 angiver du at det tilfældige tal skal ligge i:
[1; MAX_INT/(18409199*MAX_RAND)]
Men da dette skal ganges på variablen id, så skal der også deles med
"max af id fra tabellen", hvilket i mine øjne giver et ekstra udtræk fra
databasen.

Mit eksempel kræver at man lægge en øvre grænse for antallet af poster i
tabellen, men det vil typisk være begrænset over tid, mens værdien af
id-feltet vil stige, når der slettes og derefter tilføjes i databasen.

Eksempel:
Min test-tabel har 5 poster med id = (1, 2, 3, 6, 8), så "max af id" =
8. Mit interval bliver derfor:
[1, (2^31 - 1) / 18409199 / 8]
hvilket pga den lave "MAX_INT" på 2^31-1 giver
[1, 14]
Havde mit "max af id" været f.eks. 100 (ikke en særlig stor tabel), så
havde intervallet været etpunktsmængden
{1}
og udtrækket havde været det samme hver gang.

> * Metoden er mere tilfældig.

Sikke noget vås!
Hvis du kigger på min metode, så er det ligefordelingen over posterne i
databasen[1], så din metode kan ikke være /mere/ tilfældig.

Jeg prøvede at implementere din metode således:
Randomize

' plads j i res angiver antal udtræk af post med id j
Dim res(10)
For x = 0 To 9
res(x) = 0
Next

For x = 1 To 1000

iRnd = CLng(Rnd * 2147483647 / 18409199 / 8) - 1
sql = "SELECT TOP 1 id FROM tabel " & _
"ORDER BY (id*" & iRnd & "*18409199) Mod 99989"

Set rs = executeWithRS (db, sql)
res(rs("id")) = res(rs("id")) + 1
rs.Close

Next

For x = 1 To 9
Response.Write x & ": " & res(x) & "<br>"
Next

Håber det er korrekt forstået..?

Det gav det ikke særlig ligefordelte resultat:
1: 357
2: 75
3: 340
4: 0
5: 0
6: 0
7: 0
8: 228
9: 0

Læg mærke til at posten med id = 6 /aldrig/ er blevet udtrukket!

> * Der er mindre trafik til databasen.
> * Der er intet subselect eller left join hvilket gør forespørgslen
> MEGET hurtigere.

Det er rigtigt, og derfor er den heller ikke egnet til større tabeller,
men hvis man kun har få poster, så er det fint.

mvh Torben

[1] På nær en lille detalje, hvis to poster tildeles det samme
tilfældige to-cifrede tal, så hvis man har flere poster, så skal
antallet af cifre i Rnds være større end de to i artiklen.
Denne afvigelse fra ligefordelingen er dog ikke stor...


Michael Zedeler (08-03-2004)
Kommentar
Fra : Michael Zedeler


Dato : 08-03-04 17:20

Hej Torben,

Torben Brandt wrote:
> Michael Zedeler skrev:
>> * Metoden virker for et meget stort antal poster.
>
> Som jeg også indrømmede fra starten

Jaeh. Omvendt. Ja.

>> * Man skal næsten ikke lave nogen forbehandling af data.
>
> I dit indlæg fra 15.58 angiver du at det tilfældige tal skal ligge i:
> [1; MAX_INT/(18409199*MAX_RAND)]
> Men da dette skal ganges på variablen id, så skal der også deles med
> "max af id fra tabellen", hvilket i mine øjne giver et ekstra udtræk fra
> databasen.

Det er ikke nødvendigt hvis bare at der er langt til MAX_INT.

> Mit eksempel kræver at man lægge en øvre grænse for antallet af poster i
> tabellen, men det vil typisk være begrænset over tid, mens værdien af
> id-feltet vil stige, når der slettes og derefter tilføjes i databasen.

Hvis man vil være sikker på at få alle poster eksponeret lige meget,
skal man holde sig under 100. Se nedenfor.

> Eksempel:
> Min test-tabel har 5 poster med id = (1, 2, 3, 6, 8), så "max af id" =
> 8. Mit interval bliver derfor:
> [1, (2^31 - 1) / 18409199 / 8]
> hvilket pga den lave "MAX_INT" på 2^31-1 giver
> [1, 14]

Se prime-numbers.org for en liste over mindre primtal.

>> * Metoden er mere tilfældig.
>
> Sikke noget vås!
> Hvis du kigger på min metode, så er det ligefordelingen over posterne i
> databasen[1], så din metode kan ikke være /mere/ tilfældig.

Jo. Det kan den godt. Der er en fejl i din metode, da den udtager to
tegn fra strengen med tilfældige tegn. Det betyder at udfaldsrummet kun
bliver [0;99], hvilket betyder at masser af rækker vil få tildelt samme
værdi. Dermed vil de rækker som ligger først i tabellen få større
sandsynlighed for at blive valgt. Det er din note [1] ovenfor jeg
kommenterer på. Jeg mener ikke at den er til at overse da fejlen vokser
med antallet af poster over de første 100.

> Jeg prøvede at implementere din metode således:
> Randomize
>
> ' plads j i res angiver antal udtræk af post med id j
> Dim res(10)
> For x = 0 To 9
> res(x) = 0
> Next
>
> For x = 1 To 1000
>
> iRnd = CLng(Rnd * 2147483647 / 18409199 / 8) - 1
> sql = "SELECT TOP 1 id FROM tabel " & _
> "ORDER BY (id*" & iRnd & "*18409199) Mod 99989"
>
> Set rs = executeWithRS (db, sql)
> res(rs("id")) = res(rs("id")) + 1
> rs.Close
>
> Next
>
> For x = 1 To 9
> Response.Write x & ": " & res(x) & "<br>"
> Next
>
> Håber det er korrekt forstået..?
>
> Det gav det ikke særlig ligefordelte resultat:
> 1: 357
> 2: 75
> 3: 340
> 4: 0
> 5: 0
> 6: 0
> 7: 0
> 8: 228
> 9: 0
> Læg mærke til at posten med id = 6 /aldrig/ er blevet udtrukket!

Det skyldes overflow i databasen. Det virker fint med mindre primtal
eller på databaser som kan regne med store tal. Jeg har prøvet den på
MySQL, Postgres, Oracle og Sybase - der virker den fint.

>> * Der er mindre trafik til databasen.
>> * Der er intet subselect eller left join hvilket gør forespørgslen
>> MEGET hurtigere.
>
> Det er rigtigt, og derfor er den heller ikke egnet til større tabeller,
> men hvis man kun har få poster, så er det fint.

Jeg synes bare ikke at koden er specielt elegant. Dertil kommer at min
metode også virker på tabeller med få rækker.

Mvh. Michael.


Torben Brandt (08-03-2004)
Kommentar
Fra : Torben Brandt


Dato : 08-03-04 17:45

Michael Zedeler skrev:
> Torben Brandt wrote:
>>> * Man skal næsten ikke lave nogen forbehandling af data.
>>
>> I dit indlæg fra 15.58 angiver du at det tilfældige tal skal ligge i:
>> [1; MAX_INT/(18409199*MAX_RAND)]
>> Men da dette skal ganges på variablen id, så skal der også deles med
>> "max af id fra tabellen", hvilket i mine øjne giver et ekstra udtræk
>> fra databasen.
>
> Det er ikke nødvendigt hvis bare at der er langt til MAX_INT.

Hvilket der tilsyneladende ikke er i Access.

>>> * Metoden er mere tilfældig.
>>
>> Sikke noget vås!
>> Hvis du kigger på min metode, så er det ligefordelingen over posterne
>> i databasen[1], så din metode kan ikke være /mere/ tilfældig.
>
> Jo. Det kan den godt. Der er en fejl i din metode, da den udtager to
> tegn fra strengen med tilfældige tegn. Det betyder at udfaldsrummet kun
> bliver [0;99], hvilket betyder at masser af rækker vil få tildelt samme
> værdi. Dermed vil de rækker som ligger først i tabellen få større
> sandsynlighed for at blive valgt. Det er din note [1] ovenfor jeg
> kommenterer på. Jeg mener ikke at den er til at overse da fejlen vokser
> med antallet af poster over de første 100.

Jeg angiver også i noten en måde at nedbringe denne fejl, nemlig ved at
tildele hver post et tilfældigt tal med flere cifre.
Uden at jeg har regnet på det endnu, så kan det godt være at 2 cifre er
for få, men jeg vil hævde at der ikke er noget i vejen med selve metoden.

Hvis der er over 100 poster i databasen, så er den formentlig allerede
så langsom at den ikke duer.
Men de fleste "hobby-brugere" har alligevel ikke brug for at cirkulere
mellem så mange udfald.

>> Jeg prøvede at implementere din metode således:

<snip : kode>

>> Det gav det ikke særlig ligefordelte resultat:
>> 1: 357
>> 2: 75
>> 3: 340
>> 4: 0
>> 5: 0
>> 6: 0
>> 7: 0
>> 8: 228
>> 9: 0
>
>> Læg mærke til at posten med id = 6 /aldrig/ er blevet udtrukket!
>
> Det skyldes overflow i databasen. Det virker fint med mindre primtal
> eller på databaser som kan regne med store tal. Jeg har prøvet den på
> MySQL, Postgres, Oracle og Sybase - der virker den fint.

Jeg prøvede med de andre primtal du angav andetsteds (100003 og 10003),
det giver:
1: 244
2: 120
3: 226
4: 0
5: 0
6: 87
7: 0
8: 323
9: 0

Jeg synes stadig ikke det ligner en ligefordeling. Kan du ikke give et
eksempel på en implementation (primtal + evt kode), /jeg/ kan få til at
virke i Access?

Da der stod Access i første indlæg i tråden, så er det kun det jeg
snakker om.

> Jeg synes bare ikke at koden er specielt elegant. Dertil kommer at min
> metode også virker på tabeller med få rækker.

Jeg synes heller ikke den er elegant, men den er opstået fordi flere
spurgte i gruppen efter hvordan man lavede et tilfældigt udtræk med kun
én databaseforespørgsel med Access. Og ingen svarede, så jeg gik/går
ikke ud fra det er så let.

mvh Torben


Michael Zedeler (08-03-2004)
Kommentar
Fra : Michael Zedeler


Dato : 08-03-04 18:46

hej Torben,

Torben Brandt wrote:
> Michael Zedeler skrev:
>
>> Torben Brandt wrote:
>>
>>>> * Man skal næsten ikke lave nogen forbehandling af data.
>>>
>>>
>>> I dit indlæg fra 15.58 angiver du at det tilfældige tal skal ligge i:
>>> [1; MAX_INT/(18409199*MAX_RAND)]
>>> Men da dette skal ganges på variablen id, så skal der også deles med
>>> "max af id fra tabellen", hvilket i mine øjne giver et ekstra udtræk
>>> fra databasen.
>>
>>
>> Det er ikke nødvendigt hvis bare at der er langt til MAX_INT.
>
>
> Hvilket der tilsyneladende ikke er i Access.

Hvis man vælger nogle lavere primtal, er der stadigvæk plads til ca.
20.000 records som man kan sortere på.

> Jeg angiver også i noten en måde at nedbringe denne fejl, nemlig ved at
> tildele hver post et tilfældigt tal med flere cifre.
> Uden at jeg har regnet på det endnu, så kan det godt være at 2 cifre er
> for få, men jeg vil hævde at der ikke er noget i vejen med selve metoden.

Det kommer an på om det er iorden at metoden ikke ligefordeler resultatet.

> Hvis der er over 100 poster i databasen, så er den formentlig allerede
> så langsom at den ikke duer.

Så meget desto værre.

> Men de fleste "hobby-brugere" har alligevel ikke brug for at cirkulere
> mellem så mange udfald.

Det tror jeg ikke på. Der kan sagtens være brug for at finde tilfældige
rækker i større databaser selv om at det kun er på hobby-basis. Desuden
har folk svært ved at huske præmisserne for hvornår noget kode ikke
virker længere.

> Jeg prøvede med de andre primtal du angav andetsteds (100003 og 10003),
> det giver:
> 1: 244
> 2: 120
> 3: 226
> 4: 0
> 5: 0
> 6: 87
> 7: 0
> 8: 323
> 9: 0

Du trækker 1 fra dit tilfældige tal hvilket betyder at det en gang
imellem giver nul. Det er en fejlkilde, omend det ikke forklarer det
mærkelige resultat.

> Jeg synes stadig ikke det ligner en ligefordeling. Kan du ikke give et
> eksempel på en implementation (primtal + evt kode), /jeg/ kan få til at
> virke i Access?

Jeg har ikke adgang til VBScript herfra, men jeg har checket selve
metoden med de anførte tal i et andet miljø hvor det giver en fordeling
som er noget pænere.

> Da der stod Access i første indlæg i tråden, så er det kun det jeg
> snakker om.

Og jeg snakker om et generelt princip som bør kunne overføres til Access.

> Jeg synes heller ikke den er elegant, men den er opstået fordi flere
> spurgte i gruppen efter hvordan man lavede et tilfældigt udtræk med kun
> én databaseforespørgsel med Access. Og ingen svarede, så jeg gik/går
> ikke ud fra det er så let.

Det lyder spændende. Jeg vil gerne prøve at se om der er en god metode
som man kan bruge i Access. Det er klart at begrænsningen på
heltalsberegninger i Access begrænser min metodes anvendelsesmuligheder.

Mvh. Michael.


Torben Brandt (09-03-2004)
Kommentar
Fra : Torben Brandt


Dato : 09-03-04 16:48

Michael Zedeler skrev:
> Torben Brandt wrote:
>> Jeg angiver også i noten en måde at nedbringe denne fejl, nemlig ved
>> at tildele hver post et tilfældigt tal med flere cifre.
>> Uden at jeg har regnet på det endnu, så kan det godt være at 2 cifre
>> er for få, men jeg vil hævde at der ikke er noget i vejen med selve
>> metoden.
>
> Det kommer an på om det er iorden at metoden ikke ligefordeler resultatet.

Jeg indrømmer at den ikke er fuldstændig ligefordelt, men da jeg ikke
kan få din metode til at give en ligefordeling, så vælger jeg indtil
videre at negligere min rimelig lille afvigelse.

>> Jeg synes heller ikke den er elegant, men den er opstået fordi flere
>> spurgte i gruppen efter hvordan man lavede et tilfældigt udtræk med
>> kun én databaseforespørgsel med Access. Og ingen svarede, så jeg
>> gik/går ikke ud fra det er så let.
>
> Det lyder spændende. Jeg vil gerne prøve at se om der er en god metode
> som man kan bruge i Access. Det er klart at begrænsningen på
> heltalsberegninger i Access begrænser min metodes anvendelsesmuligheder.

Håber din metode kan bringes til at fungere bedre end min :)

mvh Torben


Torben Brandt (09-03-2004)
Kommentar
Fra : Torben Brandt


Dato : 09-03-04 17:38

Michael Zedeler skrev:
> Jeg har ikke adgang til VBScript herfra, men jeg har checket selve
> metoden med de anførte tal i et andet miljø hvor det giver en fordeling
> som er noget pænere.

Jeg har prøvet din metode igen[1] og det ser ud til at fordelingen
afhænger af hvilke poster (id'er) der i tabellen.
Hvis jeg prøver med min test-tabel (id'er: 1,2,3,6,8) så kan jeg ikke få
mere end 7,5% ssh for at udtrække posten med id 6.
Tabellen med id'er: 2,4,6,8,10 giver også skæve resultater.

Kan du evt prøve med denne specifikke tabel i et miljø, hvor du mener
metoden giver pæne resultater?

/Torben

[1] Denne gang ikke i en database, men bare et program, der er beregnet
til matematik.


Jens Gyldenkærne Cla~ (08-03-2004)
Kommentar
Fra : Jens Gyldenkærne Cla~


Dato : 08-03-04 17:19

Michael Zedeler skrev:

> Jeg bruger ikke Access, men kan så godt som garantere at det
> virker i Access. Er det et problem?

Det er - i mine øjne - et problem når du angiver en metode uden at
vide om det virker i Access. Specielt fordi du slet ikke tager
nogen forbehold i dit oprindelige indlæg
(<news:ah%2c.106424$jf4.6385020@news000.worldonline.dk>)


> Jeg har lige checket det i Access. Grunden til at det ikke
> virker er at den ikke kan håndtere så store tal. Jeg ved ikke
> hvor store tal den kan håndtere, så det må du checke selv.
> Hvis jeg hælder disse primtal ind, virker det:
>
> 100003 og 10003

Fint.


> Nogle databaser tillader at man udelader AS - det gør Access
> tilsyneladende ikke.

Netop.


>> Vil du ikke godt fortælle hvilke databaser det virker i?
>
> Alle SQL-kompatible databaser.

Nej - *princippet* virker (formentlig) i alle sql-kompatible
databaser. Men som tråden viser med al tydelighed, så virker det
eksempel du gav ikke generelt i alle sql-databaser.


> Hvem har egentlig pisset på din sukkermad? Det jeg skriver
> bruger et almindeligt princip for generering af
> pseudotilfældige tal. At der er nogle fejl er selvfølgelig
> beklageligt, men de fejl som jeg skrev i det oprindelige
> indlæg er nemme at rette op på hvis man ellers forstår den
> undeliggende mening.

Det er netop problemet. Du forklarer intet om hvordan teknikken
virker, så medmindre man kender den i forvejen, er det ret svært at
gennemskue de fejl du omtaler. Jeg kender en del til brugen af sql,
men jeg kunne slet ikke finde hoved eller hale i sql-koden i dit
eksempel.

Jeg blev irriteret fordi du åbenbart ikke selv havde brugt tid på
at undersøge om din metode virkede med det program (Access) der
blev spurgt om. Hvis man ikke er stensikker på at en løsning virker
generelt, bør man anføre det i sit indlæg.


> Dertil er metoden stadigvæk langt bedre end et outer join i et
> subselect med tredobbelt skrue

Det skal jeg slet ikke afvise. I MSSQL er det dog lettere bare at
benytte ORDER BY newID(), men det er ikke relevant for Access-
brugere. Din metode ser ud til at virke fint når først den er
tilpasset - jeg synes bare du skulle have testet den i et relevant
miljø før du bragte den.
--
Jens Gyldenkærne Clausen
Svar venligst under det du citerer, og citer kun det der er
nødvendigt for at forstå dit svar i sammenhængen. Se hvorfor og
hvordan på http://usenet.dk/netikette/citatteknik.html

Michael Zedeler (08-03-2004)
Kommentar
Fra : Michael Zedeler


Dato : 08-03-04 17:27

hej Jens,

Jens Gyldenkærne Clausen wrote:

> Michael Zedeler skrev:
>
>>Jeg bruger ikke Access, men kan så godt som garantere at det
>>virker i Access. Er det et problem?
>
> Det er - i mine øjne - et problem når du angiver en metode uden at
> vide om det virker i Access. Specielt fordi du slet ikke tager
> nogen forbehold i dit oprindelige indlæg
> (<news:ah%2c.106424$jf4.6385020@news000.worldonline.dk>)

Du synes at jeg skal tænke alle detaljerne igennem - jeg synes på den
anden side at folk selv skal regne den slags ud. Det er hjælp til
selvhjælp - ikke mere end som så.

> [klip]

> Nej - *princippet* virker (formentlig) i alle sql-kompatible
> databaser. Men som tråden viser med al tydelighed, så virker det
> eksempel du gav ikke generelt i alle sql-databaser.

Jeps. Der var en håndfuld fejl. Det beklager jeg.

> [klip] Du forklarer intet om hvordan teknikken
> virker, så medmindre man kender den i forvejen, er det ret svært at
> gennemskue de fejl du omtaler. Jeg kender en del til brugen af sql,
> men jeg kunne slet ikke finde hoved eller hale i sql-koden i dit
> eksempel.

Jeg vil gerne forklare princippet bag hvis nogen gider at spørge....

> Jeg blev irriteret fordi du åbenbart ikke selv havde brugt tid på
> at undersøge om din metode virkede med det program (Access) der
> blev spurgt om. Hvis man ikke er stensikker på at en løsning virker
> generelt, bør man anføre det i sit indlæg.

Jeg er stensikker på at den virker i Access. Faktisk skrev jeg at man
skulle vælge nogle passende primtal netop fordi at jeg vidste at der
kunne være et problem med overflow. Jeg kan nærmest vende argumentet om
og påstå at du ikke har læst mit indlæg grundigt nok...

>>Dertil er metoden stadigvæk langt bedre end et outer join i et
>>subselect med tredobbelt skrue
>
> Det skal jeg slet ikke afvise. I MSSQL er det dog lettere bare at
> benytte ORDER BY newID(), men det er ikke relevant for Access-
> brugere.

En anden ting er at det ikke virker på andre databaser end lige MS SQL.

> Din metode ser ud til at virke fint når først den er
> tilpasset - jeg synes bare du skulle have testet den i et relevant
> miljø før du bragte den.

Det har jeg ikke tid til, så bedre bliver det ikke.

M.


Jens Gyldenkærne Cla~ (08-03-2004)
Kommentar
Fra : Jens Gyldenkærne Cla~


Dato : 08-03-04 22:46

Michael Zedeler skrev:

>> Det er - i mine øjne - et problem når du angiver en metode
>> uden at vide om det virker i Access. Specielt fordi du slet
>> ikke tager nogen forbehold i dit oprindelige indlæg

> Du synes at jeg skal tænke alle detaljerne igennem

Nej - jeg synes bare ikke du skal love mere end du kan holde. Når
der specifikt spørges til en random-løsning til Access og du
kommenterer på en mulighed der specifikt retter sig mod Access, så
synes jeg det er ret logisk at antage at din løsning _også_ retter
sig mod (eller i hvert fald virker i) Access.

Det er ikke spørgeren eller andre deltagere der skal gætte hvilke
forbehold der gælder i et svar.

> - jeg synes på den anden side at folk selv skal regne den slags
> ud. Det er hjælp til selvhjælp - ikke mere end som så.

Vi er enige om at usenet er hjælp til selvhjælp. Jeg mener bare at
det svar du gav var mere vild- end vejledende på grund af alle de
forbehold der ikke var taget.


> Jeg vil gerne forklare princippet bag hvis nogen gider at
> spørge....

Jeg vil gerne spørge - jeg er faktisk stadig nysgerrig for at vide
hvordan det virker.


> Jeg er stensikker på at den virker i Access. Faktisk skrev jeg
> at man skulle vælge nogle passende primtal netop fordi at jeg
> vidste at der kunne være et problem med overflow. Jeg kan
> nærmest vende argumentet om og påstå at du ikke har læst mit
> indlæg grundigt nok...

Hm - jeg har lige læst dit indledende indlæg endnu en gang. Her er
hvad du skrev om primtallene:

,--------
| De to primtal skal vælges så hjøt som muligt. primtal_1 skal dog
| helst være en del større end primtal_1. I en konkret applikation
| har jeg valgt:
|
| primtal_1 := 18409199
| primtal_2 := 99989
`--------

Der var ingen advarsler om overløbsrisikoen i det indledende
indlæg.
--
Jens Gyldenkærne Clausen
»Diplomatiet består netop i, at de gamle kommatister kan få lov til
at tro, at de har vundet. Men i virkeligheden har de tabt.«
Ole Togeby i Information

Michael Zedeler (09-03-2004)
Kommentar
Fra : Michael Zedeler


Dato : 09-03-04 09:47

Hej Jens,

Jens Gyldenkærne Clausen wrote:
> Michael Zedeler skrev:

>>Du synes at jeg skal tænke alle detaljerne igennem
>
> Nej - jeg synes bare ikke du skal love mere end du kan holde. Når
> der specifikt spørges til en random-løsning til Access og du
> kommenterer på en mulighed der specifikt retter sig mod Access, så
> synes jeg det er ret logisk at antage at din løsning _også_ retter
> sig mod (eller i hvert fald virker i) Access.
>
> Det er ikke spørgeren eller andre deltagere der skal gætte hvilke
> forbehold der gælder i et svar.

Der er altid mange forbehold. Man kunne lige så godt spørge om min
løsning også virker i Access 1.0 eller noget andet i den stil. Det er en
afvejning hvilke forbehold man skal gøre opmærksom på og hvad læseren
selv skal regne ud.

Jeg mener at når man ser nogle store tal, er det fuldstændig indlysende
at checke at de miljøer de bliver brugt i kan håndtere dem.

>>Jeg vil gerne forklare princippet bag hvis nogen gider at
>>spørge....
>
>
> Jeg vil gerne spørge - jeg er faktisk stadig nysgerrig for at vide
> hvordan det virker.

Produktet p := primtal_1 * nøgle * random er med stor sandsynlighed
indbyrdes prim med tallet primtal_2. Mao. er det usandsynligt at
primtal_2 skulle gå op i p. Det betyder at resultaterne for p %
primtal_2 bliver pænt fordelt i intervallet [1;primtal_2].

Iøvrigt er der masser af andre metoder. Se
http://www.mathcom.com/corpdir/techinfo.mdir/scifaq/q210.html

>>Jeg er stensikker på at den virker i Access. Faktisk skrev jeg
>>at man skulle vælge nogle passende primtal netop fordi at jeg
>>vidste at der kunne være et problem med overflow. Jeg kan
>>nærmest vende argumentet om og påstå at du ikke har læst mit
>>indlæg grundigt nok...
>
> Hm - jeg har lige læst dit indledende indlæg endnu en gang. Her er
> hvad du skrev om primtallene:
>
> ,--------
> | De to primtal skal vælges så hjøt som muligt. primtal_1 skal dog
> | helst være en del større end primtal_1. I en konkret applikation
> | har jeg valgt:
> |
> | primtal_1 := 18409199
> | primtal_2 := 99989
> `--------
>
> Der var ingen advarsler om overløbsrisikoen i det indledende
> indlæg.

Hvis jeg skriver "så højt som muligt" hvad for andre kriterier skulle
der være andet end overløb? Med andre ord: hvad forstår du ved
bemærkningen "så højt som muligt"?

Iøvrigt tror jeg at man kan lave en pæn tilfældigt-udtræk-metode som kan
virke med små tal. Jeg vil lige undersøge det nærmere og vende tilbage.

Mvh. Michael.

Torben Brandt (09-03-2004)
Kommentar
Fra : Torben Brandt


Dato : 09-03-04 17:56

Michael Zedeler skrev:
> Produktet p := primtal_1 * nøgle * random er med stor sandsynlighed
> indbyrdes prim med tallet primtal_2. Mao. er det usandsynligt at
> primtal_2 skulle gå op i p. Det betyder at resultaterne for p %
> primtal_2 bliver pænt fordelt i intervallet [1;primtal_2].
>
> Iøvrigt er der masser af andre metoder. Se
> http://www.mathcom.com/corpdir/techinfo.mdir/scifaq/q210.html

Jeg går ud fra du mener metoden LCG med b = 0.
Hvis det er, mener jeg, at du bruger forkert.

Metoden er beregnet til at danne en række af tilfældige tal (x_1, x_2,
x_3, ...). Hvor x_n afhænger af x_{n-1}.
Her vil vi tilknytte disse tal til posterne i databasen.

Men som du ser i metoden, så skal x_n afhænge af x_{n-1}, men i din
implementation, så er x_{n-1}, der kaldes seed'et, et tal, der afhænger
af id'et i den aktuelle post, og ikke noget i den forrige post.


Det vi har gang i er ikke at danne (x_1, x_2, ...) efter LCG-metoden og
så knytte x_1 til post_1 og x_2 til post_2 osv

I stedet sætter vi x_1 til post_1, men så starter vi forfra (og bruger
ikke noget vi har regnet ud) på en ny LCG-række (y_1, y_2, ...) og
sætter y_1 til post_2.
Så starter vi på en ny LCG-række igen, z_1, z_2, ..., og sætter z1 til
post_3.

På denne måde har post_1 tallet x_1, post_2 har y_1 og post_3 har z_1.
Men (x_1, y_1, z_1, ...) er ikke dannet ud fra LCG-metoden, så du kan
ikke derudfra konkludere at de er ligefordelt.


/Torben


Jens Gyldenkærne Cla~ (09-03-2004)
Kommentar
Fra : Jens Gyldenkærne Cla~


Dato : 09-03-04 10:07

Michael Zedeler skrev:

> Der er altid mange forbehold. Man kunne lige så godt spørge om
> min løsning også virker i Access 1.0 eller noget andet i den
> stil.

Nej. Hvor mange personer tror du der anvender Access 1.0 i
forbindelse med asp? Man må tage udgangspunkt i hvilke versioner
der er i brug i dag. Når der skrives "Access" uden at nævne mere,
går jeg ud fra at der tales om Access 2000 - evt. 97 eller 2002 (i
mange tilfælde er forskellene mellem de versioner så små at de ikke
har betydning for et svar).


> Produktet p := primtal_1 * nøgle * random er med stor
> sandsynlighed indbyrdes prim med tallet primtal_2. Mao. er det
> usandsynligt at primtal_2 skulle gå op i p. Det betyder at
> resultaterne for p % primtal_2 bliver pænt fordelt i
> intervallet [1;primtal_2].

Tak for forklaringen.


> Hvis jeg skriver "så højt som muligt" hvad for andre kriterier
> skulle der være andet end overløb?

Du forudsætter at en gennemsnitsbruger i asp-gruppen selv ved (og
husker) at der kan opstå problemer med overløb. Det mener jeg ikke
er tilfældet (sammenlign hvad der i øvrigt spørges om i gruppen).


> Iøvrigt tror jeg at man kan lave en pæn
> tilfældigt-udtræk-metode som kan virke med små tal. Jeg vil
> lige undersøge det nærmere og vende tilbage.

Du skal være mere end velkommen. En velafprøvet og effektiv random-
metode til Access (og evt. andre databaser) vil helt sikkert være
til gavn for mange.
--
Jens Gyldenkærne Clausen
Svar venligst under det du citerer, og citer kun det der er
nødvendigt for at forstå dit svar i sammenhængen. Se hvorfor og
hvordan på http://usenet.dk/netikette/citatteknik.html

Søg
Reklame
Statistik
Spørgsmål : 177501
Tips : 31968
Nyheder : 719565
Indlæg : 6408527
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste