Reputation: 4527
I'm trying to SELECT
random pages that haven't been liked or disliked by a certain user (user-id: uid
) yet.
My table structure:
OneNight_pages
: (id, title) OneNight_pages_likes
: (id, page_id, uid, status)
And this is how I tried to get a random page:
SELECT
p.id AS page_id,
p.title,
SUM(CASE WHEN l.page_id = p.id AND status = '1' THEN 1 ELSE 0 END) AS likes,
SUM(CASE WHEN l.page_id = p.id AND status = '0' THEN 1 ELSE 0 END) AS dislikes
FROM OneNight_pages_likes l
LEFT JOIN OneNight_pages p on l.page_id = p.id
WHERE l.uid != '1'
GROUP BY page_id
ORDER BY rand()
LIMIT 1
However this will still display pages that I already liked or disliked, because WHERE l.uid != 1
doesn't affect to exclude a whole l.page_id
(because there are other likers and dislikers for a particular page_id).
I guess I need to solve this with a subquery to receive a page id first or use some specific algorithm? I also thought of storing all liked and disliked pages as an array in a cookie or session, but I don't know if that's the right or efficient way to do it?
Upvotes: 5
Views: 215
Reputation: 1269593
Is this what you want?
select p.*
from OneNight_pages p
where not exists (select 1
from OneNight_pages_likes l
where l.page_id = p.id and l.uid = '1'
)
order by rand()
limit 1;
This selects a random page where user "1" has no rows in the likes table.
EDIT:
This variation on your query should do about the same thing:
SELECT p.id AS page_id, p.title,
SUM(CASE WHEN status = '1' THEN 1 ELSE 0 END) AS likes,
SUM(CASE WHEN status = '0' THEN 1 ELSE 0 END) AS dislikes
FROM OneNight_pages p LEFT JOIN
OneNight_pages_likes l
ON l.page_id = p.id
GROUP BY page_id
HAVING SUM(l.uid = 1) = 0
ORDER BY rand()
LIMIT 1;
The previous version should have better performance.
Upvotes: 4