0

在 Postgres 中处理两个表:Members 和 Memberships。如果成员资格仍在运行,则成员资格有一个 end_date 列,该列可以为 NULL。一旦它结束,或者结束日期已知(可能是未来),该字段就会填充日期。

现在我想找到所有目前没有活跃会员资格的会员(或者:只有设置了 end_dates 并且过去的会员资格或 0 个会员资格)。成员显然可以拥有超过 1 个成员。

我在 Rails (3.2) 项目中执行此操作,并且希望能够在可能的情况下使用 ActiveRecord,但如有必要,直接使用 SQL 即可(尽管我更了解 ActiveRecord)。

我试图用子查询找到各种各样的东西,但我找不到一种方法来选择相关表中特定行的计数为 0 的行。

我已经在谷歌上搜索了很长一段时间,但是已经没有关于如何搜索的想法了。大多数答案都涉及查找符合标准的记录,我觉得我不想要那些不匹配的记录。也许这是一个新手问题,或者我的目标是错误的。在那种情况下:请赐教,我才刚刚开始。

根据 Jakub 的部分回答,我尝试了更多。目前我有以下查询:

选择
  m.id, m.first_name, m.last_name, COUNT (ms.id) AS n_memberships
从
  成员 AS m
LEFT JOIN 成员身份为 ms
开 m.id = ms.member_id
按 m.id、ms.end_date 分组
HAVING (max(ms.end_date) < now() AND NOT COUNT(ms.end_date = NULL) > 0) OR COUNT(ms.id) = 0;

这将返回所有没有成员资格的成员(没有过去也没有现在)。基于 HAVING 子句的最后一部分(OR ... 部分)。但是,我确实希望具有过期会员资格且没有当前会员资格的会员也能返回,因为 max(ms.end_date) 将返回一个小于现在的值,并且没有给定结束日期的会员资格将不存在。但是,这不会发生,有什么想法吗?

4

1 回答 1

1

What you're looking for is an OUTER JOIN. The SQL code to find members with no memberships is:

SELECT m.id
FROM members AS m
LEFT JOIN memberships AS s
   ON m.id=s.member_id
WHERE s.id IS NULL;

The full query:

SELECT m.id
FROM members AS m
LEFT JOIN memberships AS s
   ON m.id=s.member_id
GROUP BY m.id
HAVING max(s.end_date)<now() OR max(s.end_date) IS NULL
于 2013-06-22T21:31:16.370 回答