SQL: присоединиться, если нет в таблице или выбрать только одну строку - PullRequest
0 голосов
/ 26 марта 2019

У меня есть четыре таблицы: одна из пользователей, одна из профилей (профили пользователей), одна из отношений между профилем и контентом и одна из контента. В этой таблице содержимого не может быть ни одной, ни одной, ни нескольких записей для профиля пользователя.

Я хотел бы получить всех пользователей, у которых нет записи в таблице содержимого, или, если у них есть несколько записей, получить только одну.

Вот мой текущий 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

Я попытался добавить простое JOIN, чтобы получить только один результат из таблицы содержимого, и это работает. Но при этом я не получаю пользователей без записи в таблице содержимого.

Я застрял на несколько часов и много чего пробую ... Заранее спасибо за помощь!

РЕДАКТИРОВАТЬ:

пример пользователя

id
8
9
10

пример профиля:

id uid
2000 8
2001 9
2002 10

пример content_for_profile:

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

пример содержимого:

id uid
100 8
101 9
102 9 

ожидаемый результат:

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

1 Ответ

1 голос
/ 26 марта 2019

для получения пользователя без записи в таблице содержимого вы можете использовать где условие для нуля

    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

Вы не должны использовать GROUP BY без функции агрегации. это устарело - это больше всего дБ, и оно не разрешено в самой последней версии mysql

а чтобы получить только одну запись для значения содержимого, вы можете использовать функцию агрегации, например 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...