Mike said:
A full and complete explanation of this was provided by Bob
Barrows very early on in this thread, where he discusses the
fact that you can't order by an alias in Jet SQL, so you need
to order by the ordinal position of the calculated column.
I generally try to stay out of Access threads, but I have been following
this one, and I have to ask why anyone even bothers to create a column for
the random value. It is not required.
Working from the tried & true SQL Server favorite...
SELECT ... ORDER BY NEWID()
....I wondered if the same would work in Access. So I opened a connection to
the Northwind database and tried:
RS = CN.Execute(
"SELECT TOP 1 * FROM Employees " +
"ORDER BY Rnd(EmployeeID*" + -Math.random() + ")"
)
This is obviously in JScript, but the principle is the same -- There is no
need to squabble over the column number, since we do not return the random
number in a column.
This particular example is a poor random generator -- I ran this 10,000
times and got a distribution like this:
Record 1 : 100
Record 2 : 122
Record 3 : 1526
Record 4 : 1584
Record 5 : 1302
Record 6 : 1412
Record 7 : 1232
Record 8 : 1487
Record 9 : 1235
When normalized so the highest value is 100, this has a standard deviation
of 36.64. Not good. But when I added another Rnd to the mix, the
distribution got flatter:
RS = CN.Execute(
"SELECT TOP 1 * FROM Employees " +
"ORDER BY Rnd(Rnd(EmployeeID*" + -Math.random() + "))"
)
Record 1 : 1462
Record 2 : 1389
Record 3 : 1115
Record 4 : 937
Record 5 : 982
Record 6 : 1027
Record 7 : 1094
Record 8 : 996
Record 9 : 998
Normalized standard deviation: 12.81. I ran this test a couple of times, and
noticed a slight bias toward record 1, so I jacked it up to 50,000 (this
required me to pump up Server.ScriptTimeout), and got this:
7504
7282
5350
4723
4818
5329
5158
4825
5011
(Std dev: 14.21). There definitely seems to be a bias toward the lowest
values. I made one last adjustment (sign change on inner Rnd)...
RS = CN.Execute(
"SELECT TOP 1 * FROM Employees " +
"ORDER BY Rnd(-Rnd(EmployeeID*" + -Math.random() + "))"
)
....and ran it 180,000 times. This yielded the following distribution:
20529
22977
20013
17616
19926
21250
20085
17665
19939
This is much better, with normalized standard deviation of 7.19. Probably
random enough for most needs. My conclusion? Jimmy could get by with this:
Randomize()
Set oRS=oConn.Execute("SELECT TOP 1 EMAIL_ADDRESS FROM TABLE1 ORDER BY
Rnd(-Rnd(ID*" & -Rnd & "))")