Random row from random derived table - mysql

I've a set of tables and I want to select a random row from within a random one of the tables.
If there's 5 tables
Table1
Table2
Table3
Table4
Table5
Each has the same data format.
I've tried the below, the first part in selecting a random table works but grabbing the info from the table is returning 0 rows.
SELECT * FROM (SELECT `cat_table_name` from `category-defines` GROUP BY `cat_table_name` LIMIT 1) AS x ORDER BY RAND() LIMIT 3

Not every task can be done in a single SQL query.
In SQL, all table names (really, all identifiers) must be fixed at the time the query is parsed. You can't write an SQL query that makes choices of tables (or columns, etc.) based on expressions evaluated during the query.
By analogy: it would be like in any other code, trying to call a function whose name is based on the return value of the function you want to call.
So you can't do what you want in one query.
You could pick the random table name in one query, then use that result as you form the next query.
SELECT `cat_table_name` from `category-defines` GROUP BY `cat_table_name` LIMIT 1
SELECT * FROM `$result_from_previous_query` ORDER BY RAND() LIMIT 3
That's the simplest solution.
Be sure to delimit your table name in back-ticks, just in case one of the table names is FROM or some other reserved keyword.
(Note: the first query above doesn't pick a random table name, it always picks the first table).
A comment above suggests a UNION of all the tables. This is what that would look like:
SELECT *
FROM
(SELECT FLOOR(RAND()*5)+1 AS table_num) AS r
JOIN (
(SELECT 1 AS table_num, * FROM my_table1 ORDER BY RAND() LIMIT 3)
UNION
(SELECT 2 AS table_num, * FROM my_table2 ORDER BY RAND() LIMIT 3)
UNION
(SELECT 3 AS table_num, * FROM my_table3 ORDER BY RAND() LIMIT 3)
UNION
(SELECT 4 AS table_num, * FROM my_table4 ORDER BY RAND() LIMIT 3)
UNION
(SELECT 5 AS table_num, * FROM my_table5 ORDER BY RAND() LIMIT 3)
) AS x USING (table_num)
But this has at least two problems:
It bears the performance cost of picking random rows from every table, just to throw away most of them. Wasteful.
You still have to know the table names in advance, so if they aren't fixed, you end up running another query before this one to get the list of table names.

That is because the main query will be executed on the result of the derived table (in this case the table name), not the actual table name.
As far as my MySQL knowledge stretches you have to split this into two queries, where the first query retrieves the table name and the second query uses the result from the first query. In PHP it would look something like this
//get a random table name
$stmt = $this->pdo->prepare('SELECT `cat_table_name` as table from `category-defines` GROUP BY `cat_table_name` LIMIT 1');
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
//select 3 random rows with the table name
$stmt = $this->pdo->prepare('SELECT * FROM '.$row['table'].' ORDER BY RAND() LIMIT 3');
$stmt->execute();
$randomRows = $stmt->fetchAll(PDO::FETCH_ASSOC); //the three random rows

Related

Union, order by and RAND() in mySQL

I want to have a union of two request BUT the order by rand() of the second one doesn't work..
(select * from survey
where is_priority = 1)
union all (
select * from (
select * from survey
order by rand()
) as t );
The result look like this :
I speculate that you want is_priority = 1 first followed by the rest in random order.
If so, you should not do this with union all. Just add the right keys to the order by:
select s.*
from survey s
order by (s.is_priority = 1) desc, -- put priority 1 first in the result set
rand();
Admittedly, this puts the top priority rows in random order (amongst them). But you haven't specified an order for them (and this is a non-issue if there is only one row where the priority condition is true).

Mysql SELECT function inside mysql LIMIT function

SELECT COUNT('2018-02-12')
as ids FROM tg_partner_data
WHERE assign_to = '2'
AND
followup_date = '2018-02-12' AND active='Y'
LIMIT (SELECT count FROM tg_master_count WHERE count_for = 'followup')
I tried to get count as output but this query doesnot works . I am using like this because the limit setting is dynamic.
An immediate problem with your use of LIMIT is that you have no ORDER BY clause. Which first records do you expect from the result set? This is not clear. I will give a generic pattern which you can use to have a subquery limit the number of records.
Consider a simple table with just one column:
col
1
2
3
4
5
Now let's say that you want to limit the number of records in the result set, based on an ordering of col, using some subquery. We can write the following:
SET #rn=0;
SELECT col
FROM
(
SELECT
col,
#rn:=#rn+1 rn
FROM yourTable
ORDER BY
col
) t
WHERE t.rn <= (SELECT 3 FROM dual); -- replace with your own subquery
Demo
The basic idea here is that we simulate row number in a subquery, that is, we assign a row number to each record, ordered according the the col column. Then we subquery that table, and retain only records matching the subquery you want to use to limit.

how to select random user

i have the following table with its fields, this table has more than 30K user's,
EACH USE'r has more than 1000 records,
userid is named as ANONID , i want to select randomly 100 user with all their records,using MYSQL
thanks in advance
"rand()" function as mentioned in earlier answers do not work in SQL 2k12 . for SQL use following query to get random 100 rows using "newid()" function
("newid()" is built in function for SQL)
select * from table
order by newid()
offset 0 rows
fetch next 100 rows only
For a table of 30,000 and a single sample, you can use:
select t.*
from t
order by rand()
limit 100;
This does exactly what you want. It will take a few seconds to return.
If performance is an issue, there are other more complicated methods for sampling the data. A simple method reduces the number of rows before the order by. So a 5% sample will speed the query and here is one method for doing that:
select t.*
from t
where rand() < 0.05
order by rand()
limit 100;
EDIT:
You want what is called a clustered sample or hierarchical sample. Use a subquery:
select t.*
from t join
(select userid
from (select distinct userid from t) t
order by rand()
limit 100
) tt
on t.userid = tt.userid;
SELECT * FROM table
ORDER BY RAND()
LIMIT 100
It is slow, but it works.

Last 5 entries or more depending on where

I want to run a query where the last 5 entries are always returned, which is simple: SELECT * FROM table ORDER BY id DESC LIMIT 5. But I want to get more than 5 if a certain condition applies, which by itself would simply be something like SELECT * FROM table WHERE field > value. Is there a way to do this as a single query or do I have to run 2?
Maybe with UNION?. Like:
(SELECT * FROM table ORDER BY id DESC LIMIT 5)
UNION
(SELECT * FROM table WHERE field > value)

How can I get a random order of returned rows in mysql query

I have MySQL query, that returns set of rows. What I need is to get them in random order, each time that the query is executed.
For example, I have query
SELECT id,id_banner,name FROM module_banner
And it returns me 3 rows with ids - 1,2,3
I want to get them in random order - 3,2,1 2,3,1 1,3,2 and so on.
Let me know if the question is not clear
P.S.
Is there solution without RANDOM() function ?
You want to use ORDER BY RAND():
SELECT id,id_banner,name FROM module_banner ORDER BY RAND()
Just add ORDER BY RAND() at the end of your query.
Query in-general will be
SELECT field1, field2, ... , field(n) FROM TableName ORDER BY RAND()
In your case it would be
SELECT id, id_banner, name FROM module_banner ORDER BY RAND()
Update 1
While searching I found one article & You should read this article : "Do not use ORDER BY RAND() or How to get random rows from table?"
SELECT id,id_banner,name
FROM module_banner JOIN
(SELECT CEIL(RAND() *
(SELECT MAX(id)
FROM module_banner)) AS id
) AS r2
USING (id);
Reference