1

我有在 PostgreSQL 数据库中按成员资格加入组的用户的行为。

我有一个查询来为排行榜生成行。但是,它目前排除了 Acts 表不包含具有相应users_id. 我想包括所有小组成员,即使是那些 0 Acts 的成员。

当前查询:

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在 users 之前更改为RIGHT JOINand LEFT JOIN,但我得到了相同的结果。在某一时刻,我认为这RIGHT JOIN是有效的,但不知何故,我出了差错。

4

3 回答 3

1

我想包括所有小组成员,即使是那些 0 Acts 的成员。

跳线:

  1. 如果你想包含 0 Acts 的成员,你不能 return acts.users_id。改为使用 memberships.users_id
  2. 子句中的条件a.created_at >= (CURRENT_DATE - 6)使所有使用. 将该条件移到子句中。看: WHERELEFT JOINJOIN
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.

还假设“所有组成员”是指 all WHERE m.groups_id = ' + req.params.group_id + ',或者我们需要做更多。

但是你到底在数什么?目前,这看起来像是具有组成员身份的行为的乘法。可能是误会。看:

根据确切的表定义和您想要计算的内容,确切地说,可能会有更快的查询......

于 2019-10-09T00:38:58.633 回答
1

我以前也遇到过这样的问题。我要做的是删除所有 where 语句和连接。首先左加入用户以仅执行操作,然后查看查询是否保留了您想要的非活动用户同样尝试用户会员之间的左连接。一旦您查询了两个表,其中的用户在 ACT 表中不存在。将第三个表与前两个表的输出连接起来。然后最后应用您的 where 语句并按计数分组。

于 2019-10-09T01:04:37.933 回答
0

如果要返回没有行为的用户,则需要从行为以外的其他表开始。例如,您可以尝试从 users 表而不是行为开始:

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

这应该返回所有用户,即使他们没有行为或会员资格。

于 2019-10-08T23:06:23.310 回答