I am facing some unusual issue. Please help. There are 300 rows in a column. I want to display any 100 order by rand(). But within this randomly selected 100, there must be 2 rows. How can I write it?
Example:
"Select id from sample_table where id<300 or id>1 order by rand() limit 100"
But I want the result must include id=34 and id=78
Use UNION ALL to select the 2 rows that must exist in the results and 98 random rows:
select id from sample_table
where id in (34, 78)
union all
select id from (
select id from sample_table
where where id not in (34, 78)
order by rand() limit 98
) t
order by rand()
or simpler with conditional sorting:
select * from (
select id from sample_table
order by id not in (34, 78), rand()
limit 100
) t
order by rand()
Union both to the original SELCT and random the result of that union
SELECT
id
FROM
(SELECT 34 UNION SELECT 78 UNION SELECT
id
FROM
sample_table
WHERE
id < 300 OR id > 1
ORDER BY RAND()
LIMIT 98)
ORDER BY RAND()
Related
The following is my db table:
id category_id name
--------------------
1 4 A
2 5 B
3 6 C
I have four simple select queries which pull 15 rows by random from specific categories:
select * from table where category_id = 4 order by rand() limit 15;
select * from table where category_id = 5 order by rand() limit 15;
select * from table where category_id = 6 order by rand() limit 15;
select * from table where category_id = 7 order by rand() limit 15;
I want to combine them into a single query rather than four separate queries. I've tried using the UNION operator but it wasn't pulling 15 rows EQUALLY from each category:
(
select * from table where category_id = 4
union
select * from table where category_id = 5
union
select * from table where category_id = 6
union
select * from table where category_id = 7
) order by rand() limit 60;
How can I achieve this? Or, do I have to run separate queries?
I've tagged Laravel because I'm using Laravel as the backend and maybe Eloquent has a smarter way to achieve this.
Have you tried this one?:
(select * from table where category_id = 4 ORDER BY rand() LIMIT 15)
union all
(select * from table where category_id = 5 ORDER BY rand() LIMIT 15)
union all
(select * from table where category_id = 6 ORDER BY rand() LIMIT 15)
union all
(select * from table where category_id = 7 ORDER BY rand() LIMIT 15)
you could use CTE and ROW_NUMBER() as such
WITH CTE AS (
SELECT id,
category_id,
ROW_NUMBER() OVER(PARTITION BY category_id
ORDER BY RAND() DESC) AS rank
FROM table)
SELECT *
FROM CTE
WHERE rank <= 15 AND category_id IN (4,5,6,7)```
I want to run a query like this, so that I will always get 20 results, even if the 1st SELECT statement does not have enough data to return 10 results.
(
SELECT t.column1, t.column2
FROM table t
WHERE t.status = 1
LIMIT 10
)
UNION
(
SELECT t.column1, t.column2
FROM table t
WHERE t.status = 2
LIMIT 20
)
LIMIT 20
But I then want to ORDER BY RAND() and make sure that all the available results from the first SELECT statement are included in the final result set.
When I add ORDER BY RAND() to the end of this query, it gives me result sets that do not include all 10 results from the first SELECT, I assume because it is really getting 30 rows and then choosing 20 at random from the 30.
Any ideas would be appreciated.
Here is what worked for me:
SELECT x.*
FROM ((
SELECT t.column1, t.column2
FROM table t
WHERE t.status = 1
LIMIT 10
)
UNION
(
SELECT t.column1, t.column2
FROM table t
WHERE t.status = 2
LIMIT 20
)
LIMIT 20) x
ORDER BY RAND
Should work if you order your UNION results by what SELECT they are “from” first, before the LIMIT 20 is applied:
SELECT … FROM
(
(
SELECT t.column1, t.column2, 0 AS ordervalue FROM … WHERE …
LIMIT 10
)
UNION
(
SELECT t.column1, t.column2, 1 FROM … WHERE …
LIMIT 20
)
ORDER BY ordervalue ASC # this will make the values from your first SELECT come
# first, then the ones from the second
LIMIT 20 # of those ordered values, the first 20 are taken
)
ORDER BY RAND()
I introduced a static value as ordervalue here – in your special case it would not be necessary, since you select by status 1 or 2, so you could order by that value directly. But if that was not the case (or the status values would be different), that “pseudo” column value would be the way to go.
I'm wonder if there is way to use LIMIT operator to always include first row in result set. I mean regardless of any range specified. For Ex:
SELECT * FROM `table` LIMIT 5, 10
should return first row and row 6 to 15 or:
SELECT * FROM `table` LIMIT 200, 30
should return first row and row 201 to 231. Is there a way to do that ?
Edit First row id is always 0
I don't see another way :
(SELECT * from table LIMIT 1)
UNION
(SELECT * FROM table LIMIT 5, 10)
or as Pointed by Scott, with new infos ;)
SELECT * from table Where id = 0
UNION
(SELECT * FROM table LIMIT 5, 10)
don't forget brackets :
To apply ORDER BY or LIMIT to an individual SELECT, place the clause
inside the parentheses that enclose the SELECT:
(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10) UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);
You can use UNION to connect 2 selects: (SELECT * FROM table LIMIT 1) UNION (SELECT * FROM table LIMIT 5, 10)
Here's a query:
SELECT *
FROM table
WHERE id = 1
OR id = 100
OR id = 50
Note that I provided the ids in this order: 1,100,50.
I want the rows to come back in that order: 1,100,50.
Currently, i comes back 1,50,100 - basically in ascending order. Assume the rows in the table were inserted in ascending order also.
Use the MySQL specific FIND_IN_SET function:
SELECT t.*
FROM table t
WHERE t.id IN (1, 100, 50)
ORDER BY FIND_IN_SET(CAST(t.id AS VARCHAR(8)), '1,100,50')
Another way to approach this would put the list in a subquery:
select table.*
from table join
(select 1 as id, 1 as ordering union all
select 100 as id, 2 as ordering union all
select 50 as id, 3 as ordering
) list
on table.id = list.id
order by list.ordering
You can just do this with ORDER BY:
ORDER BY
id = 1 DESC, id = 100 DESC, id = 50 DESC
0 is before 1 in ORDER BY.
Try this
SELECT *
FROM new
WHERE ID =1
OR ID =100
OR ID =50
ORDER BY ID=1 DESC,ID=100 DESC,ID=50 DESC ;
http://www.sqlfiddle.com/#!2/796e2/5
... WHERE id IN (x,y,x) ORDER BY FIELD (id,x,y,z)
How would I combine (stack vertically) the following 3 queries into one query that returns 100 rows, 50 rows from category 1, 25 from from category 2, 25 from category 3 all chosen randomly. I tried UNION but didn't seem to work.
select * from table where category_id = 1 order by rand() limit 50;
select * from table where category_id = 2 order by rand() limit 25;
select * from table where category_id = 3 order by rand() limit 25;
To apply ORDER BY or LIMIT to an individual SELECT, place the clause inside the parentheses that enclose the SELECT:
(select * from table where category_id = 1 order by rand() limit 50)
UNION ALL
(select * from table where category_id = 2 order by rand() limit 25)
UNION ALL
(select * from table where category_id = 3 order by rand() limit 25);
What you are looking for is the UNION ALL syntax (link is to MySQL documentation).
select * from table where category_id = 1 order by rand() limit 50
UNION ALL
select * from table where category_id = 2 order by rand() limit 25
UNION ALL
select * from table where category_id = 3 order by rand() limit 25;
edit: Semicolons removed, thanks #Matt Fenwick