MySQL select 3 UNIQUE random ID rows fast WHERE

I need to be able to select 3 Unique random MySQL ID rows from a table that is progressively growing and growing over time, AND have a WHERE 'status' = 'available'. So it only picks the id number if status = available.

There will be no gaps as all data is kept for record keeping compliance, if data is deleted by the user it is not actually deleted just STATUS is marked 'deleted'.

I've read many posts about the subject but it all seems to boil down to picking just 1 result, and then repeating it 3 times, problem is, it might pick the same ID again, so any solution to my problem will be much appreciated.

Thank you

:)

I was looking at doing something like this (taken from here ... MySQL select 10 random rows from 600K rows fast)

SELECT id
  FROM table AS r1 JOIN
       (SELECT (RAND() *
                     (SELECT MAX(id)
                        FROM table)) AS id2)
        AS r2
 WHERE r1.id >= r2.id2 AND status = 'available'
 ORDER BY r1.id ASC
 LIMIT 1

Which gives me what I need, but it only returns 1 random Unique 'pick', plus IF I limit it to 3, it does not always pick 3, and if it does pick 3 they always seem to be sequential which is not random!

Is there a way to repeat the query, store the ID picked and keep looping / running the query until 3 ID's are picked AT RANDOM that are Different. This is my question :)

Answers


Did you try:

SELECT *
FROM mytable
WHERE status = 'available'
ORDER BY RAND( )
LIMIT 0,3;

SELECT DISTINCT *
FROM table
WHERE status = 'available'
ORDER BY RAND()
LIMIT 3

The DISTINCT clause shall prevent repeated values. ORDER BY RAND() will randomly organize the result.


See the following; where it talks about "gaps", you have the equivalent (status=deleted) http://mysql.rjweb.org/doc.php/random#case_auto_increment_with_gaps_1_or_more_rows_returned (and look around in that link for variants)

  • Requirement: AUTO_INCREMENT, possibly with gaps due to DELETEs, etc
  • Flaw: Only semi-random (rows do not have an equal chance of being picked), but it does partially compensate for the gaps
  • Flaw: The first and last few rows of the table are less likely to be delivered.

This gets 50 "consecutive" ids (possibly with gaps), then delivers a random 10 of them.

-- First select is one-time:
SELECT @min := MIN(id),
       @max := MAX(id)
    FROM RandTest;
SELECT a.*
    FROM RandTest a
    JOIN ( SELECT id FROM
            ( SELECT id
                FROM ( SELECT @min + (@max - @min + 1 - 50) *
                         RAND() AS start FROM DUAL ) AS init
                JOIN RandTest y
                WHERE    y.id > init.start
                ORDER BY y.id
                LIMIT 50           -- Inflated to deal with gaps
            ) z ORDER BY RAND()
           LIMIT 10                -- number of rows desired
         ) r ON a.id = r.id;

Yes, it is complex, but yes, it is fast, regardles of the table size.


Need Your Help

Displaying an image link contained in JSON response from Instagram API?

java android api instagram instagram-api

Hey so I am trying to display images in an Android app whos image urls are packaged into a JSON response from the /users/user-id/media/recent Instagram api call.

SimpleDateFormat And Arabic Locale

android arabic simpledateformat

I want to format my date to Arabic locale but it doesn't work on my Galaxy Tab2 also doesn't work on Galaxy Note and gives me two different results.