Reputation: 443
Sorry for the very fuzzy question but my problem is that I have three different tables. One table containing user information, one for the users posts and one for the users likes. I want to select data from the tables containing the users data and posts but only return a post that the user have not liked and not is posted by the user itself. I have tried to use different combinations of JOINS
but with no success.
For example i want to select the rows for the user with id = 1.
Table users:
+----+----------+
| id | username |
+----+----------+
| 1 | A |
| 2 | B |
| 3 | C |
+----+----------+
Table posts:
+----+---------+
| id | user_id |
+----+---------+
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
| 4 | 3 |
| 5 | 2 |
| 6 | 3 |
+----+---------+
Table likes:
+----+---------+---------+
| id | post_id | user_id |
+----+---------+---------+
| 1 | 3 | 2 |
| 2 | 3 | 1 |
| 3 | 4 | 1 |
| 4 | 1 | 3 |
+----+---------+---------+
Result wantend:
+---------+----------+
| post_id | username |
+---------+----------+
| 5 | B |
| 6 | C |
+---------+----------+
A problem I run into is that my query also returns post_id: 3
because user_id: 2
have liked the post.
I hope that you understands my question.
Thanks in Advance! /Andreas
Upvotes: 8
Views: 11079
Reputation:
SELECT p.id, u.username
FROM stackoverflow.posts p
JOIN stackoverflow.users u ON p.user_id = u.id
WHERE user_id <> 1
AND
p.id NOT IN
(
SELECT likes.post_id
FROM stackoverflow.likes
WHERE user_id = 1
);
Upvotes: 1
Reputation: 780974
To find rows that don't have a match in another table, use a LEFT JOIN
and then select the rows where the foreign key is NULL
.
SELECT p.id as post_id, u.username
FROM posts p
LEFT JOIN likes l ON l.post_id = p.id AND l.user_id = 1
JOIN users u
WHERE u.id != 1 and l.post_id IS NULL
Upvotes: 3
Reputation: 4549
I think your data model isn't quite right, if "liking" a post adds a use to the "posts" table.
However, to answer your original question, you can exclude "liked" posts this way:
SELECT p.post_id, p.user_id FROM
post p LEFT JOIN
likes l
ON p.post_id = l.post_id WHERE l.post_id IS NULL;
Upvotes: 8
Reputation: 1269753
Here is an approach to the query that uses not exists
for the likes
:
select p.id as post_id, u.username
from posts p join
users u
on p.user_id = u.id
where not exists (select 1
from likes l
where l.post_id = p.id and l.user_id = 1
) and
u.id <> 1;
Upvotes: 7