When using RND()
in Access Database Engine SQL from outside of the Access UI, the same sequence of random numbers will be used by each session (there is no native support for VBA's Randomize).
For example, connect to the source then execute SELECT RND();
three times in succession, you will get the following values:
0.705547511577606
0.533424019813538
0.579518616199493
Close the connection, connect to the source again then execute the same query again three times you will get the same three values as above in the same order.
In the knowledge that these values are predictable, we can demonstrate that a different value for RND()
is used each time it is referenced. Consider this query:
SELECT RND()
FROM T
WHERE RND() > CDBL(0.6);
We know the first value in a new session will be 0.705547511577606
, therefore the expression
RND() > CDBL(0.6)
will evaluate TRUE
. However, the value 0.533424019813538
is repeated for every row in table T
, a value which does not satisfy the WHERE
clause! So it is clear that the value of RND()
in the WHERE
clause is different from the value in the SELECT
clause. The full code is posted below.
Note I wondered if it may be possible to use the least significant portion of CURRENT_TIMESTAMP
value generate a random number that could be used consistently through the scope of a single query and not be predictable for a session as RND()
is. However, the Access Database Engine does not support it and its closest analogy, the NOW()
function, does not have enough granularity to be useful :(
Sub jmgirpjpo()
On Error Resume Next
Kill Environ$("temp") & "\DropMe.mdb"
On Error GoTo 0
Dim cat
Set cat = CreateObject("ADOX.Catalog")
With cat
.Create _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & _
Environ$("temp") & "\DropMe.mdb"
With .ActiveConnection
.Execute "CREATE TABLE T (T INT);"
.Execute "INSERT INTO T VALUES (1);"
.Execute "INSERT INTO T VALUES (2);"
.Execute "INSERT INTO T VALUES (3);"
Dim rs
Set rs = .Execute("SELECT RND() FROM T WHERE RND() > CDBL(0.6);")
MsgBox rs.GetString
End With
End With
End Sub