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.
Related
I do know how to access last N records from the table i.e,
SELECT * FROM table_name ORDER BY auto_incremented_id DESC LIMIT N;
There are N records means and table records keep incrementing every day, each record having unique serial ID from 1 to N.
now i want to retrieve 10 records of last N-10 rows.
please consider the example
Record 1
Record 2
Record 3
Record 4
Record 5
Record 6
Record N-M
Record N-2
Record N-1
Record N
How do i can retrieve N-2 to N-M rows
The solution required for an website - 1st page displays last 10 records, 2nd Page displays last next 10 records from the reverse except rows are displayed in first page and it goes on up to 1st record of the table.
you can play with ordering and your limit conditions
SELECT * from (SELECT * from table_name ORDER BY auto_incremented_id DESC LIMIT N) as temp ORDER BY auto_incremented_id ASC LIMIT M
assuming as you say a paging size of 10
first page:
SELECT * from as temp ORDER BY auto_incremented_id DESC LIMIT 10;
second page:
SELECT * from (SELECT * from table_name ORDER BY auto_incremented_id DESC LIMIT 20) as temp ORDER BY auto_incremented_id ASC LIMIT 10;
third page:
SELECT * from (SELECT * from table_name ORDER BY auto_incremented_id DESC LIMIT 30) as temp ORDER BY auto_incremented_id ASC LIMIT 10;
For dynamically limiting the output rows you can use inline views (as MySQL doesn't support common table expressions using WITH clause). An example code is as follows:
SELECT *
FROM (SELECT id, name
, #i := #i + 1 as result
FROM table_name
, (select #i := 0) temp
ORDER BY id) v
CROSS JOIN (SELECT COUNT(id) AS M FROM table_name) w
WHERE result BETWEEN w.m-2 AND w.m;
Fiddle.
I would like to select a random record from a table but with a bias toward higher values in a particular field -- I don't want any record to have a 0% chance of getting selected, just less likely to get selected.
From this article, I know that random selects can be slow and you can speed them up:
http://wanderr.com/jay/order-by-slow/2008/01/30/
But what about when you are dealing with a few tables with joins and a where statement, and want to use one of the fields as a way to bias the randomness (the higher this field's value, the more likely to get selected)? For example:
SELECT a.id, a.date, a.userid, b.points FROM table_a AS a INNER JOIN table_b AS b ON (a.userid = b.userid) WHERE DATE_SUB(CURDATE(), INTERVAL 60 DAY) <= a.date
How could I turn the above into an efficient but not truly random query that would be biased toward higher values of b.points?
my 2 cents, biased can be carried out like this:
Assuming the Score is between 0, 100.
You randomly choose 5 records that is >75, 3 recording >50, 2 record >25, 1 record >0
Now if you random again from this 11 records, it is biased toward higher score.
To put them in sql, called your joined table "abc"
Select * from (
select * from abc where b.points > 75 order by rand() limit 5
cross join
select * from abc where b.points > 50 and b.points <75 order by rand() limit 3
cross join
select * from abc where b.points > 25 and b.points <50 order by rand() limit 2
cross join
select * from abc where b.points > 0 and b.points <25 order by rand() limit 1
) as result
order by rand() limit 3
Performance wise, I'll have a look at your link and update this anwser.
How do I write a query to find the Nth maximum value in MySQL?
SELECT column FROM table ORDER BY column DESC LIMIT (n-1), 1
Have a look at http://php.about.com/od/mysqlcommands/g/Limit_sql.htm for reading up on LIMIT on SQL:
Definition: Limit is used to limit your MySQL query results to those that fall within a specified range. You can use it to show the first X number of results, or to show a range from X - Y results. It is phrased as Limit X, Y and included at the end of your query. X is the starting point (remember the first record is 0) and Y is the duration (how many records to display).
SELECT date FROM t1 WHERE date =(
SELECT DISTINCT(date ) FROM t1 AS SSELWS WHERE
(SELECT COUNT(DISTINCT(date))-1 FROM t1 )=
(
SELECT COUNT(DISTINCT(date ))+1 FROM t1 AS s2 WHERE SSELWS.date >s2.date ORDER BY s2.date ASC
) ORDER BY SSELWS.date ASC)
Select * from world w1 where (N-1) = (Select
Count(distinct(population)) from world w2 where w2.population >
w1.population)
The Maximum Value for a Column:
SELECT MAX([column_name]) AS [alias] FROM [table_name];
I'm using full text search to pull rows.
I order the rows based on score (ORDER BY SCORE) , then of the top 20 rows (LIMIT 20), I want to rand (RAND) the result set.
So for any specific search term, I want to randomly show 5 of the top 20 results.
My workaround is code based- where I put the top 20 into an array then randomly select 5.
Is there sql way to do this?
You can do this using an inner select. Select the top twenty rows in the inner select. In the outer select order these rows randomly and select the top five:
SELECT *
FROM (
SELECT *
FROM table1
ORDER BY score DESC
LIMIT 20
) AS T1
ORDER BY RAND()
LIMIT 5
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.