简体   繁体   中英

MySQL - Exclude all rows from one table if match on another table

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

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;

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;

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
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
        );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM