Оператор SQL JOIN возвращает только элементы с ассоциацией - PullRequest
0 голосов
/ 09 октября 2019

У меня есть Акты пользователей, которые присоединились к группам по членству в базе данных PostgreSQL.

У меня есть запрос на генерацию строк для таблицы лидеров. Однако в настоящее время он исключает пользователей, в которых таблица Acts не содержит строки с соответствующим users_id. Я хочу включить всех членов группы, даже тех, кто имеет 0 актов.

Текущий запрос:

SELECT acts.users_id, username, avatar_url, COUNT(acts.id) 
FROM acts 
JOIN users ON acts.users_id = users.id 
JOIN memberships on memberships.users_id = users.id 
WHERE memberships.groups_id = ' + req.params.group_id + ' 
AND acts.created_at >= (CURRENT_DATE - 6) 
GROUP BY acts.users_id, username, avatar_url 
ORDER BY COUNT(acts.id) DESC

Я пытался изменить JOIN перед пользователями на RIGHT JOIN и LEFT JOIN, но я получаю тот же результат. В какой-то момент я думаю, что RIGHT JOIN работал, но каким-то образом я ошибся.

Ответы [ 3 ]

1 голос
/ 09 октября 2019

Я хочу включить всех членов группы, даже тех, у кого 0 Актов.

Отключающие провода:

  1. Если вы хотите включить членов с 0 Актами,вы не можете вернуть acts.users_id. Вместо этого используйте memberships.users_id.
  2. Условие a.created_at >= (CURRENT_DATE - 6) в предложении WHERE аннулирует все попытки с LEFT JOIN. Переместите это условие в предложение JOIN. См .:
SELECT m.users_id  -- !!!
     , u.username, avatar_url
     , COUNT(a.users_id) AS ct_acts
FROM   memberships m
JOIN   users       u ON m.users_id = u.id 
LEFT   JOIN acts   a ON a.users_id = u.id 
                    AND a.created_at >= (CURRENT_DATE - 6)  -- !!!
WHERE  m.groups_id = ' + req.params.group_id + '
GROUP  BY 1, 2, 3
ORDER  BY COUNT(*) DESC;

Предполагая ссылочную целостность между memberships и users (Ограничение FK), поэтому присоединение к пользователям может оставаться как [INNER] JOIN.

. Также предполагается, что «все члены группы» подразумевают все WHERE m.groups_id = ' + req.params.group_id + ', или нам нужно сделать больше.

Но что именно вы там считаете? В настоящее время это выглядит как умножение актов с участием в группах. Может быть недоразумение. См .:

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

1 голос
/ 09 октября 2019

У меня были такие проблемы раньше. Что бы я сделал, это удалил все операторы where и соединения. Начните с левого присоединения users к actions only и посмотрите, сохраняет ли запрос неактивных пользователей, которых вы хотели. Аналогичным образом попробуйте левое объединение между пользователями и членствами . После того, как у вас есть запрос двух таблиц с пользователями, которых нет в таблице ACT. Присоединитесь к третьей таблице с выводом первых двух. И, наконец, примените свое утверждение where и сгруппируйте по количеству.

0 голосов
/ 09 октября 2019

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

SELECT acts.users_id, username, avatar_url, COUNT(acts.id) 
FROM users
LEFT JOIN acts ON acts.users_id = users.id 
LEFT JOIN memberships on memberships.users_id = users.id 
WHERE memberships.groups_id = ' + req.params.group_id + ' 
AND acts.created_at >= (CURRENT_DATE - 6) 
GROUP BY acts.users_id, username, avatar_url 
ORDER BY COUNT(acts.id) DESC

Это должно вернуть вам всех пользователей, даже если у них нет действий или членства.

...