I have 2 MySQL tables, namely posts
and votes
The posts table contains articles published by authors (users).
The votes table contains votes against the particular post by users.
I’d like to get all posts that have or haven’t been voted on by the current user.
What MySQL statement should I write to achieve the desired result?
Table 1 posts contains 4 columns.post_id
is the primary key, and author_id
stores user_id
from user table.
post_id (int-11) |
title (text) |
author_id (int-11) |
created (datetime) |
---|---|---|---|
1 | This is 1st Post | 2 | 2023-02-24 14:43:49 |
2 | This is 2nd Post | 5 | 2023-02-26 18:16:17 |
3 | This is 3rd Post | 1 | 2023-03-01 05:42:51 |
4 | This is 4th Post | 2 | 2023-03-01 08:20:15 |
5 | This is 5th Post | 8 | 2023-03-02 12:35:49 |
Table 2 votes contains 4 columns.vote_id
is the primary key, and post_id
& author_id
store values from the foreign tables, namely post and user. vote
column can store enum(‘approve’, ‘reject’)
vote_id (int-11) |
post_id (int-11) |
user_id (int-11) |
vote enum(‘approve’, ‘reject’) |
---|---|---|---|
1 | 4 | 2 | approve |
2 | 2 | 3 | reject |
3 | 3 | 3 | reject |
4 | 1 | 2 | approve |
How to get all post rows that are not voted on by the current user or voted by the current user. (both condition seperately)
Also, how do I get the number of votes for a particular post in the same SQL statement?
Desired Result (Not Voted)
user_id = 3
is the current user.
user_id = 3
has already voted for post_id 2 & 3
.
Except for post_id = 2 & 3, all rows should be returned.
post_id (int-11) |
title (text) |
author_id (int-11) |
created (datetime) |
---|---|---|---|
1 | This is 1st Post | 2 | 2023-02-24 14:43:49 |
4 | This is 4th Post | 2 | 2023-03-01 08:20:15 |
5 | This is 5th Post | 8 | 2023-03-02 12:35:49 |
I tried this SQL to fetch all rows for which the current user (3) has votes, but it is showing all rows.
SELECT p.*, v.*
FROM `posts` p
LEFT JOIN `votes` v ON p.post_id = v.post_id
LEFT JOIN `votes` v2 on p.post_id = v2.post_id and v2.user_id='3';
2
Answers
For example:
and
WHERE v.user_id <> 3
for teh other case.
If I understood correctly.
The main problem of you have tried: The current user filter is part of left outer join.
To get the result you want, you can use NOT IN operator and post_id from votes to buid your query: