mysql random rows - mysql

how to form a query to select 'm' rows randomly from a query result which has 'n' rows.
for ex; 5 rows from a query result which has 50 rows
i try like as follows but it errors
select * from (select * from emp where alphabet='A' order by sal desc) order by rand() limit 5;
u can wonder that why he needs sub query, i need 5 different names from a set of top 50 resulted by inner query.

SELECT * FROM t
ORDER BY RAND() LIMIT 5
or from your query result:
SELECT * FROM ( SELECT * FROM t WHERE x=y ) tt
ORDER BY RAND() LIMIT 5

This will give you the number to use as 'm' (limit)
TRUNCATE((RAND()*50),0);
...substitute 50 with n.
To check it try the following:
SELECT TRUNCATE((RAND()*50),0);
I should warn that this could return 0 as a result, is this ok for you?
For example you could do something like this:
SELECT COUNT(*) FROM YOUR_TABLE
...and store the result in a variable named totalRows for example. Then you could do:
SELECT * FROM YOUR_TABLE LIMIT TRUNCATE((RAND()*?),0);
where you substitute the '?' with the totalRows variable, according to the tech stack you are using.
Is it clearer now? If not please add more information to your question.

Related

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.

LIMIT by random number between 1 and 10

Essentially, I want to return X number of records from the last 21 days, with an upper limit of 10 records.
How do I add a random LIMIT to a query in MySQL?
Here's my query, with X for the random number 1-10.
SELECT releases.id, COUNT(charts_extended.release_id) as cnt FROM releases
INNER JOIN charts_extended
ON charts_extended.release_id=releases.id
WHERE DATEDIFF(NOW(), releases.date) < 21
GROUP BY releases.id
ORDER BY RAND()
LIMIT 0, X
I tried using RAND() * 10 + 1, but it gives a syntax error.
Is there any way to do this using pure SQL; ie without using an application language to "build" the query as a string and have the application language fill in X programmatically?
Eureka...
In pseudo code:
execute a query to select 10 random rows
select from that assigning a row number 0-9 using a user defined variable to calculate that
cross join with a single hit on rand() to create a number 0-9 and select all rows with row number less than or equal to that number
Here's the essence of the solution (you can adapt your query to work with it:
select * from (
select *, (#row := coalesce(#row + 1, 0)) row from (
// your query here, except simply LIMIT 10
select * from mytable
order by rand()
limit 10
) x
) y
cross join (select rand() * 10 rand) z
where row <= rand
See SQLFiddle. Run it a few times and you'll see you get 1-10 random rows.
If you don't want to see the row number, you can change the outer select * to select only the specific columns from the inner query that you want in your result.
Your query is correct but you need to update limit clause.
$query = "SELECT releases.id, COUNT(charts_extended.release_id) as cnt FROM releases
INNER JOIN charts_extended
ON charts_extended.release_id=releases.id
WHERE DATEDIFF(NOW(), releases.date) < 21
GROUP BY releases.id
ORDER BY RAND()
LIMIT 0,".rand(1,10);
and then execute this query.

How can I limit query's results without using LIMIT

I need to show ordered 20 records on my grid but I can't use LIMIT because of my generator(Scriptcase) using LIMIT to show lines per page. It's generator's bug but I need to solve it for my project. So is it possible to show 20 ordered record from my table with a query?
As from comments,if you can't use limit then you can rank your results on basis of some order and in parent select filter limit the results by rank number
select * from (
select *
,#r:=#r + 1 as row_num
from your_table_name
cross join (select #r:=0)t
order by some_column asc /* or desc*/
) t1
where row_num <= 20
Demo with rank no.
Another hackish way would be using group_concat() with order by to get the list of ids ordered on asc/desc and substring_index to pick the desired ids like you need 20 records then join with same table using find_in_set ,But this solution will be very expensive in terms of performance and group_concat limitations if you need more than 20 records
select t.*
from your_table_name t
join (
select
substring_index(group_concat(id order by some_column asc),',',20) ids_list
from your_table_name
) t1 on (find_in_set(t.id , t1.ids_list) > 0)
Demo without rank
What about SELECT in SELECT:
SELECT *
FROM (
-- there put your query
-- with LIMIT 20
) q
So outer SELECT is without LIMIT and your generator can add own.
In a Scriptcase Grid, you CAN use Limit. This is a valid SQL query that selects only the first 20 records from a table. The grid is set to show only 10 records per page, so it will show 20 results split in a total of 2 pages:
SELECT
ProductID,
ProductName
FROM
Products
LIMIT 20
Also the embraced query works out well:
SELECT
ProductID,
ProductName
FROM
(SELECT
ProductID,
ProductName
FROM Products LIMIT 20) tmp

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

Selecting some results of SQL query

From a simple SQL query in MySQL how can I get only the 5 first results?
And then, how can I get the next 5 results?
For example (pseudo code):
select * from (select * from some_table) where <first 5 results>
select * from (select * from some_table) where <second 5 results (6-10)>
You should be able to get the first 5 results with a LIMIT 5 at the end of your statement:
SELECT * FROM some_table LIMIT 5;
And then you can get results 6-10 with a query like this:
SELECT * FROM some_table LIMIT 5 OFFSET 5;
As another example, you could get results 6-15 with a query like this:
SELECT * FROM some_table LIMIT 10 OFFSET 5;
Please keep in mind that, if you don't add an ORDER BY statement, the results are retrieved in arbitrary order. Consequently, it doesn't really make sense to use LIMIT and OFFSET in the absence of an ORDER BY.
You can do this by making a SQL union
select * from (select * from some_table) where <first 5 results>
UNION ALL
select * from (select * from some_table) where <second 5 results (6-10)>