Help with getting random results in a query.

odin1701

Registered User.
Local time
Yesterday, 21:07
Joined
Dec 6, 2006
Messages
526
I need some help getting random results in a query.

I have this so far, and it works, but it is slow.

SELECT TOP 1 tblMain.Field1, tblMain.Field2, Rnd(tblMain.Field2) As Expr1, ... FROM tblMain WHERE tblMain.COMPLETED=False ORDER BY Rnd(tblMain.Field2) DESC;

This does a great job actually finding a random record.

The problem is that it is slow. I have about 77,000 records currently. I will need to add I would say at least another 250,000 records to this database. So the speed will be very slow.

Is there a way to just get a quick query of say 100 records, then run the randomize query on just those records in order to choose one?

Or could I use an autonumber field set to random and have it somehow grab one of those?

My issue is that a form I have for working on these grabs one, but if I just use the TOP 1 function it will grab the same record over and over. This is an issue because only one person should work on the record at one time. So sometimes it becomes possible for more than one person to select the same record, though I tried to prevent that. I have a yes/no field which is set to yes when someone opens the record, and then the query should ignore that record. But so many people are using it, it is still happening.

Any ideas would be appreciated. Thanks!
 
I need some help getting random results in a query.

I have this so far, and it works, but it is slow.

SELECT TOP 1 tblMain.Field1, tblMain.Field2, Rnd(tblMain.Field2) As Expr1, ... FROM tblMain WHERE tblMain.COMPLETED=False ORDER BY Rnd(tblMain.Field2) DESC;

This does a great job actually finding a random record.

The problem is that it is slow. I have about 77,000 records currently. I will need to add I would say at least another 250,000 records to this database. So the speed will be very slow.

Is there a way to just get a quick query of say 100 records, then run the randomize query on just those records in order to choose one?

Or could I use an autonumber field set to random and have it somehow grab one of those?

My issue is that a form I have for working on these grabs one, but if I just use the TOP 1 function it will grab the same record over and over. This is an issue because only one person should work on the record at one time. So sometimes it becomes possible for more than one person to select the same record, though I tried to prevent that. I have a yes/no field which is set to yes when someone opens the record, and then the query should ignore that record. But so many people are using it, it is still happening.

Any ideas would be appreciated. Thanks!

Do you have some sort of RecordId on the records?
If so, you could try something like this, where you have about 77000
(you need to know how many you have)
Then use something like this to get a random record from your Table.

SELECT tblMain.Field1, tblMain.Field2, ... FROM tblMain WHERE [Your RecordId] =Round((77000*Rnd)+1);

I'm not sure what
tblMain.COMPLETED=False was doing, but if it was constraining the number of records qualifying, then you may have to get a count of records where COMPLETED = FALSE first, then do a random selection from that set.

Just some thoughts.
 
Last edited:
When a record is completed, that completed field needs to be used to exclude those records from being selected.

I don't have record ID's. Well I do. There are two fields which hold parts of an account number. Both of those fields are set to primary keys so as to prevent duplicates from being imported. There should only be one of each account number. I could ADD an autonumber, but it can't be a key.
 
When a record is completed, that completed field needs to be used to exclude those records from being selected.

I don't have record ID's. Well I do. There are two fields which hold parts of an account number. Both of those fields are set to primary keys so as to prevent duplicates from being imported. There should only be one of each account number. I could ADD an autonumber, but it can't be a key.

Do the partial account numbers have a range? I think were looking for a number that goes from the start to end of the records to be included in the random selection.

So if you have 77000 records and 20000 are complete, we/re talking 57000 records max. And to select a single random record out of that.
You might be able to adapt this and still use the 77000
Code:
SELECT id,fld2, fld3 from main
    where id = round(77000*Rnd) +1
    and exists (
      SELECT main.id
      FROM main
      WHERE (((main.COMPLETED) = FALSE)));
 
The account numbers have a range, but to get the unique range you would have a possible value from 4,000,000,000 to roughly 635,000,000,000. The second part of the account number is not necessarily uniqe but even then you would be talking about a range of anywhere from 900,000,000 to 999,999,999.


And of course I won't have all possible or existing account numbers in this database either. Just some of them. So randomly picking a valid account number won't work.
 
The account numbers have a range, but to get the unique range you would have a possible value from 4,000,000,000 to roughly 635,000,000,000. The second part of the account number is not necessarily uniqe but even then you would be talking about a range of anywhere from 900,000,000 to 999,999,999.


And of course I won't have all possible or existing account numbers in this database either. Just some of them. So randomly picking a valid account number won't work.

Well you could add an Autonumber, and not use it in the record key.
 
How could I use the autonumber for that?

Wouldn't I still end up with the same problem?

I won't always know how many total records are in the DB...or the limit to set the autonumber for. But I'll play around with it on a temp table and see what I can do.
 
Code:
SELECT id,fld2, fld3 from main
    where id = round(77000*Rnd) +1
    and exists (
      SELECT main.id
      FROM main
      WHERE (((main.COMPLETED) = FALSE)));

This works, sort of. It is faster, but only sometimes returns a record. Maybe 3 or 4 times out of 10 times it runs does it return something.
 
I figured it out!

I can't believe I didn't think of this earlier:
Code:
SELECT TOP 1 *, Rnd(tblMain.AcctNum) As Expr1 FROM (SELECT TOP 100 * FROM tblMain WHERE tblMain.COMPLETED = False AND tblMain.LOCKED = False) ORDER BY Rnd(tblMain.AcctNum) DESC;


Simply limit the selection of records to 100 and query the query. DUH!

Performance wise it's pretty much instant now.
 
Last edited:

Users who are viewing this thread

Back
Top Bottom