根据相关表中没有返回的记录查找记录

时间:2013-06-22 20:44:06

标签: ruby-on-rails-3 postgresql

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

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

我在Rails(3.2)项目中这样做,并且希望能够在可能的情况下使用ActiveRecord,但是如果需要,可以直接使用SQL(尽管我更了解ActiveRecord)。

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

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

基于Jakub的部分答案,我已经尝试了很多。目前我有以下查询:

SELECT 
  m.id, m.first_name, m.last_name, COUNT (ms.id) AS n_memberships
FROM 
  members AS m
LEFT JOIN memberships AS ms
ON m.id = ms.member_id
GROUP BY 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)将返回一个小于现在的值,并且没有给定结束日期的会员资格。这不会发生任何想法吗?

1 个答案:

答案 0 :(得分:1)

您正在寻找的是OUTER JOIN。查找没有成员资格的成员的SQL代码是:

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

完整查询:

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