Reputation: 2344
I have 2 tables; 'groups' and 'values'. I am trying to select one random row from the values table, where values.groupid = groups.id
The query I have is:
SELECT *
FROM groups as g
inner JOIN
(
SELECT * FROM values as v WHERE v.groupid = g.id ORDER BY RAND() LIMIT 1
) AS rv ON rv.groupid = g.id
v doesnt seem to have access to g how can i work around this? in regards to the random, I only managed to get the limit 1 solution to work, because there may be deleted value.id's and it is small table (only ever max 200 rows). if I only use join on, and dont have the where clause inside the join, it will select random value from any group, or return nothing. can anyone help me?
edit: this wont work either because I cannot access v from outside this time
SELECT g.*
,(SELECT * FROM v ORDER BY RAND() LIMIT 1)
FROM groups AS g
JOIN
(
SELECT * FROM values
) AS v ON v.groupid = g.id
I see many other question very similar but, none actually try to do a join on the value for each group in effect .. if I am missing one please just mention and I will delete issue, i will continually look at others but in the mean time I am still needing help. thank you
Upvotes: 2
Views: 3845
Reputation: 562310
I always avoid using ORDER BY RAND()
with SQL, it causes terrible performance unless your dataset is really small. And if your dataset is that small, you'd still be better off fetching all the rows into your application and picking a random row.
Here's a solution that I just tested, and it works to pick one random row from each group:
SELECT g.*, v.*
FROM Groups AS g
INNER JOIN (
SELECT groupid, COUNT(*) AS c, 1+FLOOR(RAND()*COUNT(*)) AS random
FROM `Values` GROUP BY groupid
) AS c ON g.id = c.groupid
INNER JOIN (SELECT @g:=0, @r:=0) AS init
INNER JOIN (
SELECT IF(groupid<>@g, @r:=1, @r:=@r+1) AS rank, @g:=groupid AS groupid, value
FROM `Values`
ORDER BY groupid
) AS v ON g.id = v.groupid AND c.random = v.rank
Upvotes: 5
Reputation: 2344
SELECT u.login, a.filename FROM users u
JOIN (SELECT filename, user_id, id AS rand_id FROM assets ORDER BY RAND()) a
ON u.id = a.user_id
WHERE a.filename IS NOT NULL
GROUP BY user_id
ORDER BY u.login;
Upvotes: 0