简体   繁体   中英

SQL : join if not in table or select only one row

I have four tables : one of users, one of profiles (users profiles), one of relations between profile and content and one of content. That content table could have no entry, single or multiple entry for a user profile.

I would like to get all the users who have no entry in the content table or if they have multiple entries, get only one.

Here is my current SQL :

SELECT
users.uid AS uid,
profile.id AS profile_id,
content.id AS content_id
FROM 
users users_data
LEFT JOIN profile profile_data ON users_data.id = profile_data.uid
LEFT JOIN content_for_profile content_profile ON profile_data.id = content_profile.pid
LEFT JOIN content content_data ON content_for_profile.content_id = content_data.id
JOIN (
SELECT content_data_join.id, content_data_join.uid
FROM content content_data_join
GROUP BY content_data_join.uid
) content_data_join ON content_for_profile.content_id=content_data_join.id
GROUP BY uid, profile_id, content_id
ORDER BY profile.created DESC

I tried to add the simple JOIN to get only one result from the content table and it works. But with that, i don't get users with no entry in the content table.

I've been stuck for hours and try so many things ... Thanks in advance for your help !

EDIT :

user example

id
8
9
10

profile example :

id uid
2000 8
2001 9
2002 10

content_for_profile example :

id pid content_id
1 2000 100
2 2001 101
3 2001 102

content example :

id uid
100 8
101 9
102 9 

expected result :

uid profile_id content_id
8 2000 100
9 2001 101
10 2002 NULL

for get the user without entry in content table you can use where condition for null

    SELECT
    users.uid AS uid,
    profile.id AS profile_id,
    content.id AS content_id
    FROM 
    users users_data
    LEFT JOIN profile profile_data ON users_data.id = profile_data.uid
    LEFT JOIN content_for_profile content_profile ON profile_data.id = content_profile.pid
    LEFT JOIN content content_data ON content_for_profile.content_id = content_data.id

    where content_data.id is null  

    ORDER BY profile.created DESC

You should not use GROUP BY without aggreation function. this deprecated is most db and is not allowed in the most recent version of mysql

a for get just one entry for content value the you can use an aggreation function eg min() ..max()

    SELECT
    users.uid AS uid,
    profile.id AS profile_id,
    min(content.id) AS content_id
    FROM 
    users users_data
    LEFT JOIN profile profile_data ON users_data.id = profile_data.uid
    LEFT JOIN content_for_profile content_profile ON profile_data.id = content_profile.pid
    LEFT JOIN content content_data ON content_for_profile.content_id = content_data.id

    GROUP BY users.uid ,profile.id 
    ORDER BY profile.created DESC

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